refactor: r8 build optmisations

This commit is contained in:
2026-06-10 21:49:52 +02:00
parent 3c9b480a9e
commit d1c3722781
3 changed files with 133 additions and 55 deletions
+10 -4
View File
@@ -33,6 +33,10 @@ android {
targetSdk = 36
versionCode = 1
versionName = "0.1.0"
androidResources {
localeFilters += setOf("en", "es", "eu")
}
// testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner"
@@ -52,8 +56,8 @@ android {
buildTypes {
release {
// isMinifyEnabled = true // Enables R8/ProGuard shrinking
// isShrinkResources = true // Removes unused resources
isMinifyEnabled = true // Enables R8/ProGuard shrinking
isShrinkResources = true // Removes unused resources
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
@@ -62,6 +66,8 @@ android {
}
create("benchmark") {
initWith(buildTypes.getByName("release"))
isMinifyEnabled = false // benchmarks must not be minified
isShrinkResources = false // or results are meaningless
signingConfig = signingConfigs.getByName("debug") // sign with debug key for easy deployment
installation {
enableBaselineProfile = false // ← disables profile embedding for this build type only
@@ -116,7 +122,7 @@ dependencies {
testImplementation(libs.junit)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
implementation(libs.androidx.benchmark.junit4)
androidTestImplementation(libs.androidx.benchmark.junit4)
androidTestImplementation(libs.androidx.runner)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.espresso.core)
@@ -128,7 +134,7 @@ dependencies {
implementation(libs.retrofit2.retrofit)
implementation(libs.converter.gson)
implementation(libs.okhttp)
implementation(libs.logging.interceptor)
debugImplementation(libs.logging.interceptor)
// Coroutines
implementation(libs.kotlinx.coroutines.android)
+123 -23
View File
@@ -1,24 +1,124 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# Keep all protobuf generated message classes and their fields
# ──────────────────────────────────────────────────────────────────
# Protobuf lite
# ──────────────────────────────────────────────────────────────────
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
# ──────────────────────────────────────────────────────────────────
# Google Tink 1.13.0
# ──────────────────────────────────────────────────────────────────
-keep class com.google.crypto.tink.proto.** { *; }
-keep class com.google.crypto.tink.shaded.protobuf.** { *; }
-keep class com.google.crypto.tink.** { *; }
-dontwarn com.google.crypto.tink.**
# ──────────────────────────────────────────────────────────────────
# Gson generic signature safety
# ──────────────────────────────────────────────────────────────────
-keepattributes Signature
-keepattributes *Annotation*
-keep,allowobfuscation,allowshrinking,allowoptimization class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking,allowoptimization class * extends com.google.gson.reflect.TypeToken
# ──────────────────────────────────────────────────────────────────
# Gson ALL classes Gson instantiates via reflection
# ──────────────────────────────────────────────────────────────────
# Response bodies
-keep class com.bitcointxoko.gudariwallet.api.WalletResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.PaymentStatusResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.PaymentDetails { *; }
-keep class com.bitcointxoko.gudariwallet.api.PaymentDetailResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.WithdrawCallbackResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.FiatRateResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.LnurlpLink { *; }
# NWC models
-keep class com.bitcointxoko.gudariwallet.api.NwcGetResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.NwcKey { *; }
-keep class com.bitcointxoko.gudariwallet.api.NwcBudget { *; }
-keep class com.bitcointxoko.gudariwallet.api.NwcNewBudget { *; }
-keep class com.bitcointxoko.gudariwallet.api.NwcRegistrationRequest { *; }
# Request bodies
-keep class com.bitcointxoko.gudariwallet.api.CreateInvoiceRequest { *; }
-keep class com.bitcointxoko.gudariwallet.api.PayInvoiceRequest { *; }
-keep class com.bitcointxoko.gudariwallet.api.DecodeInvoiceRequest { *; }
-keep class com.bitcointxoko.gudariwallet.api.PayLnurlRequest { *; }
# SuccessAction sealed class + TypeAdapter subclasses
-keep class com.bitcointxoko.gudariwallet.api.SuccessAction { *; }
-keep class com.bitcointxoko.gudariwallet.api.FlexibleStringAdapter
-keep class com.bitcointxoko.gudariwallet.api.SuccessActionAdapter
# Node alias API responses
-keep class com.bitcointxoko.gudariwallet.api.MempoolNodeResponse { *; }
-keep class com.bitcointxoko.gudariwallet.api.OneMlNodeResponse { *; }
# ──────────────────────────────────────────────────────────────────
# Retrofit 3.0.0
# ──────────────────────────────────────────────────────────────────
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# ──────────────────────────────────────────────────────────────────
# OkHttp 5.x / Okio
# ──────────────────────────────────────────────────────────────────
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.codehaus.mojo.animal_sniffer.*
# ──────────────────────────────────────────────────────────────────
# secp256k1-kmp (JNI)
# ──────────────────────────────────────────────────────────────────
-keep class fr.acinq.secp256k1.** { *; }
-keepclasseswithmembernames class * {
native <methods>;
}
# ──────────────────────────────────────────────────────────────────
# ZXing 4.3.0
# ──────────────────────────────────────────────────────────────────
-keep class com.google.zxing.** { *; }
-dontwarn com.google.zxing.**
# ──────────────────────────────────────────────────────────────────
# Room 2.7.1
# ──────────────────────────────────────────────────────────────────
-keep class * extends androidx.room.RoomDatabase
-keep @androidx.room.Entity class *
-dontwarn androidx.room.**
# ──────────────────────────────────────────────────────────────────
# WorkManager 2.9.1
# ──────────────────────────────────────────────────────────────────
-keep class * extends androidx.work.Worker
-keep class * extends androidx.work.CoroutineWorker
-keep class * extends androidx.work.ListenableWorker {
public <init>(android.content.Context, androidx.work.WorkerParameters);
}
# ──────────────────────────────────────────────────────────────────
# Kotlin Coroutines 1.11.0
# ──────────────────────────────────────────────────────────────────
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-dontwarn kotlinx.coroutines.**
# ──────────────────────────────────────────────────────────────────
# Lyricist 1.8.0
# ──────────────────────────────────────────────────────────────────
-keep class com.bitcointxoko.gudariwallet.**Strings { *; }
-keep class com.bitcointxoko.gudariwallet.**Translations { *; }
# ──────────────────────────────────────────────────────────────────
# Timber 5.0.1
# ──────────────────────────────────────────────────────────────────
-dontwarn org.jetbrains.annotations.**
# ──────────────────────────────────────────────────────────────────
# Stack traces upload mapping.txt to Play Console / Crashlytics
# ──────────────────────────────────────────────────────────────────
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
@@ -1,40 +1,22 @@
package com.bitcointxoko.gudariwallet.api
import com.bitcointxoko.gudariwallet.BuildConfig
import com.bitcointxoko.gudariwallet.security.SecretStore
import com.bitcointxoko.gudariwallet.util.WalletConstants
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import timber.log.Timber
import java.util.concurrent.TimeUnit
object LNbitsClient {
val logging = HttpLoggingInterceptor { message ->
Timber.tag("OkHttp").d(message)
}.apply {
level = HttpLoggingInterceptor.Level.BODY // logs full request + response body
}
// Single shared client — used by both Retrofit and WebSocket
val httpClient: OkHttpClient = OkHttpClient.Builder()
.connectTimeout(WalletConstants.CONNECT_TIMEOUT_S, TimeUnit.SECONDS)
.readTimeout(WalletConstants.READ_TIMEOUT_S, TimeUnit.SECONDS)
.writeTimeout(WalletConstants.WRITE_TIMEOUT_S, TimeUnit.SECONDS)
.addInterceptor(logging)
.apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}
.build()
fun create(secrets: SecretStore): LNbitsApi {
@@ -71,21 +53,11 @@ object LNbitsClient {
}
val client = httpClient.newBuilder()
// .addInterceptor(authInterceptor)
.addInterceptor(dynamicBaseUrlInterceptor)
.apply {
// Logging goes LAST — after URL rewrite — so logs show the real URL
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}
.build()
return Retrofit.Builder()
.baseUrl("https://placeholder.invalid/") // structurally required by Retrofit;
// always overwritten by the interceptor
.client(client)
.addConverterFactory(GsonConverterFactory.create(GsonProvider.gson))
.build()