1
0
mirror of https://github.com/dzeiocom/OpenHealth.git synced 2025-04-23 19:32:11 +00:00

feat: Support for minified/optimized builds

This commit is contained in:
Florian Bouillon 2023-01-29 22:18:45 +01:00
parent 2628bc1403
commit 615179989b
Signed by: Florian Bouillon
GPG Key ID: BEEAF3722D0EBF64
6 changed files with 68 additions and 101 deletions

View File

@ -20,6 +20,25 @@ plugins {
kotlin("kapt") kotlin("kapt")
} }
// from: https://discuss.kotlinlang.org/t/use-git-hash-as-version-number-in-build-gradle-kts/19818/8
fun String.runCommand(
workingDir: File = File("."),
timeoutAmount: Long = 60,
timeoutUnit: TimeUnit = TimeUnit.SECONDS
): String = ProcessBuilder(split("\\s(?=(?:[^'\"`]*(['\"`])[^'\"`]*\\1)*[^'\"`]*$)".toRegex()))
.directory(workingDir)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start()
.apply { waitFor(timeoutAmount, timeoutUnit) }
.run {
val error = errorStream.bufferedReader().readText().trim()
if (error.isNotEmpty()) {
return@run ""
}
inputStream.bufferedReader().readText().trim()
}
// The application ID // The application ID
val appID = "com.dzeio.openhealth" val appID = "com.dzeio.openhealth"
@ -32,6 +51,14 @@ val sdkMin = 21
// target SDK version // target SDK version
val sdkTarget = 33 val sdkTarget = 33
val branch = "git rev-parse --abbrev-ref HEAD".runCommand(workingDir = rootDir)
var tag = "git tag -l --points-at HEAD".runCommand(workingDir = rootDir)
if (tag == "") {
tag = "not tagged"
}
val commitId = "git rev-parse HEAD".runCommand(workingDir = rootDir)
.subSequence(0, 7)
android { android {
signingConfigs { signingConfigs {
@ -83,28 +110,29 @@ android {
"new String[]{\"" + locales.joinToString("\",\"") + "\"}" "new String[]{\"" + locales.joinToString("\",\"") + "\"}"
) )
resourceConfigurations += locales resourceConfigurations += locales
buildConfigField("String", "BRANCH", "\"$branch\"")
buildConfigField("String", "TAG", "\"$tag\"")
buildConfigField("String", "COMMIT", "\"$commitId\"")
} }
buildTypes { buildTypes {
getByName("release") { getByName("release") {
// Slimmer version // Slimmer version
isMinifyEnabled = false isMinifyEnabled = true
isShrinkResources = false isShrinkResources = true
isDebuggable = true isDebuggable = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"
) )
signingConfig = signingConfigs.getByName("release") signingConfig = signingConfigs.getByName("release")
} }
getByName("debug") { getByName("debug") {
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
applicationIdSuffix = ".dev" applicationIdSuffix = ".dev"
versionNameSuffix = "-dev" versionNameSuffix = "-dev"
isDebuggable = true isDebuggable = true

View File

@ -20,67 +20,7 @@
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and # do not obfuscate fields with the annotation `@SerializedName`
# EnclosingMethod is required to use InnerClasses. -keepclassmembers,allowobfuscation class * {
-keepattributes Signature, InnerClasses, EnclosingMethod @com.google.gson.annotations.SerializedName <fields>;
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Keep annotation default values (e.g., retrofit2.http.Field.encoded).
-keepattributes AnnotationDefault
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
@retrofit2.http.* <methods>;
} }
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# Keep inherited services.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt and other security providers are available.
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*

View File

@ -16,7 +16,6 @@ class Application : Application() {
} }
override fun onCreate() { override fun onCreate() {
val prefs = PreferenceManager.getDefaultSharedPreferences(this) val prefs = PreferenceManager.getDefaultSharedPreferences(this)
// setup the CrashHandler // setup the CrashHandler
@ -25,7 +24,16 @@ class Application : Application() {
.withPrefs(prefs) .withPrefs(prefs)
.witheErrorReporterCrashKey(R.string.error_reporter_crash) .witheErrorReporterCrashKey(R.string.error_reporter_crash)
.withPrefsKey(Settings.CRASH_LAST_TIME) .withPrefsKey(Settings.CRASH_LAST_TIME)
.withPrefix("${BuildConfig.APPLICATION_ID} v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})") .withPrefix(
"""
${BuildConfig.APPLICATION_ID} v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})
Build informations:
Commit: ${BuildConfig.COMMIT}
Branch: ${BuildConfig.BRANCH}
Tag: ${BuildConfig.TAG}
""".trimIndent()
)
.build() .build()
.setup(this) .setup(this)

View File

@ -3,13 +3,11 @@ package com.dzeio.openhealth.ui
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Process import android.os.Process
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.Toast import android.widget.Toast
import com.dzeio.openhealth.Application import com.dzeio.openhealth.Application
import com.dzeio.openhealth.BuildConfig
import com.dzeio.openhealth.core.BaseActivity import com.dzeio.openhealth.core.BaseActivity
import com.dzeio.openhealth.databinding.ActivityErrorBinding import com.dzeio.openhealth.databinding.ActivityErrorBinding
import kotlin.system.exitProcess import kotlin.system.exitProcess
@ -28,20 +26,8 @@ class ErrorActivity : BaseActivity<ActivityErrorBinding>() {
val data = intent.getStringExtra("error") val data = intent.getStringExtra("error")
// Get Application datas
val deviceToReport = if (Build.DEVICE.contains(Build.MANUFACTURER)) Build.DEVICE else "${Build.MANUFACTURER} ${Build.DEVICE}"
val reportText = """
Crash Report (Thread: ${intent?.getLongExtra("threadId", -1) ?: "unknown"})
${BuildConfig.APPLICATION_ID} v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})
on $deviceToReport (${Build.MODEL}) running Android ${Build.VERSION.RELEASE} (${Build.VERSION.SDK_INT})
backtrace:
""".trimIndent() + data
// put it in the textView // put it in the textView
binding.errorText.text = reportText binding.errorText.text = data
// Handle the Quit button // Handle the Quit button
binding.errorQuit.setOnClickListener { binding.errorQuit.setOnClickListener {
@ -51,14 +37,15 @@ class ErrorActivity : BaseActivity<ActivityErrorBinding>() {
// Handle the Email Button // Handle the Email Button
binding.errorSubmitEmail.setOnClickListener { binding.errorSubmitEmail.setOnClickListener {
// Create Intent // Create Intent
val intent = Intent(Intent.ACTION_SEND) val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("mailto:") intent.setDataAndType(
intent.type = "text/plain" Uri.parse("mailto:"),
"text/plain"
)
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("report.openhealth@dzeio.com")) intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("report.openhealth@dzeio.com"))
intent.putExtra(Intent.EXTRA_SUBJECT, "Error report for application crash") intent.putExtra(Intent.EXTRA_SUBJECT, "Error report for application crash")
intent.putExtra(Intent.EXTRA_TEXT, "Send Report Email\n$reportText") intent.putExtra(Intent.EXTRA_TEXT, "Send Report Email\n$data")
try { try {
startActivity(Intent.createChooser(intent, "Send Report Email...")) startActivity(Intent.createChooser(intent, "Send Report Email..."))
@ -69,14 +56,17 @@ class ErrorActivity : BaseActivity<ActivityErrorBinding>() {
// Handle the GitHub Button // Handle the GitHub Button
binding.errorSubmitGithub.setOnClickListener { binding.errorSubmitGithub.setOnClickListener {
// Build URL // Build URL
val url = "https://github.com/dzeiocom/OpenHealth/issues/new?title=Application Error&body=$reportText" val url =
"https://github.com/dzeiocom/OpenHealth/issues/new?" +
"title=Application Error&" +
"body=${data?.replace("\n", "\\n")}"
try { try {
startActivity( val intent = Intent(Intent.ACTION_VIEW).apply {
Intent(Intent.ACTION_VIEW, Uri.parse(url)) setData(Uri.parse(url))
) }
startActivity(intent)
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
Toast.makeText(this, "No Web Browser found :(", Toast.LENGTH_LONG).show() Toast.makeText(this, "No Web Browser found :(", Toast.LENGTH_LONG).show()
} }

View File

@ -21,7 +21,7 @@ class FoodDialogViewModel @Inject internal constructor(
val res = foodRepository.getById(productId) val res = foodRepository.getById(productId)
val food = res.first() val food = res.first()
if (food != null) { if (food != null) {
items.postValue(food) items.postValue(food!!)
} }
} }
} }

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout2" android:id="@+id/linearLayout2"
android:padding="16dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -11,6 +11,7 @@
android:id="@+id/textView3" android:id="@+id/textView3"
style="?textAppearanceHeadline5" style="?textAppearanceHeadline5"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:textAlignment="center"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/error_app_crash" android:text="@string/error_app_crash"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -20,6 +21,7 @@
<TextView <TextView
android:id="@+id/textView4" android:id="@+id/textView4"
android:layout_width="0dp" android:layout_width="0dp"
android:textAlignment="center"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/error_app_report" android:text="@string/error_app_report"
@ -42,6 +44,7 @@
android:id="@+id/error_text" android:id="@+id/error_text"
android:layout_width="match_parent" android:layout_width="match_parent"
style="?textAppearanceCaption" style="?textAppearanceCaption"
android:textIsSelectable="true"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</ScrollView> </ScrollView>
@ -53,7 +56,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/report_github" android:text="@string/report_github"
android:layout_marginStart="16dp"
app:layout_constraintBaseline_toBaselineOf="@+id/error_submit_email" app:layout_constraintBaseline_toBaselineOf="@+id/error_submit_email"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
@ -62,7 +64,6 @@
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/report_email" android:text="@string/report_email"
app:layout_constraintBottom_toTopOf="@+id/error_quit" app:layout_constraintBottom_toTopOf="@+id/error_quit"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />