From 097396bb936efa06e4ec3b2b555e3639a010b256 Mon Sep 17 00:00:00 2001 From: Developer Date: Mon, 1 Dec 2025 18:37:27 -0800 Subject: [PATCH] =?UTF-8?q?build:=20=E9=85=8D=E7=BD=AE=20Android=20Release?= =?UTF-8?q?=20=E7=AD=BE=E5=90=8D=E5=92=8C=E6=9E=84=E5=BB=BA=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 Release 签名配置 (build.gradle.kts) - 配置 ProGuard 混淆规则 (proguard-rules.pro) - 优化 Gradle 内存配置 (gradle.properties) - 更新 .gitignore 排除签名密钥文件 签名密钥存放于 publish/ 目录 (已排除版本控制) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- frontend/mobile-app/.gitignore | 6 +++ .../mobile-app/android/app/build.gradle.kts | 35 +++++++++++++-- .../mobile-app/android/app/proguard-rules.pro | 45 +++++++++++++++++++ frontend/mobile-app/android/gradle.properties | 9 +++- 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 frontend/mobile-app/android/app/proguard-rules.pro diff --git a/frontend/mobile-app/.gitignore b/frontend/mobile-app/.gitignore index 3820a95c..74e65684 100644 --- a/frontend/mobile-app/.gitignore +++ b/frontend/mobile-app/.gitignore @@ -43,3 +43,9 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# Release signing keys (IMPORTANT: never commit these!) +/publish/ +*.keystore +*.jks +key.properties diff --git a/frontend/mobile-app/android/app/build.gradle.kts b/frontend/mobile-app/android/app/build.gradle.kts index 8c064d01..281ee96c 100644 --- a/frontend/mobile-app/android/app/build.gradle.kts +++ b/frontend/mobile-app/android/app/build.gradle.kts @@ -1,3 +1,6 @@ +import java.util.Properties +import java.io.FileInputStream + plugins { id("com.android.application") id("kotlin-android") @@ -5,6 +8,13 @@ plugins { id("dev.flutter.flutter-gradle-plugin") } +// Load key.properties +val keyPropertiesFile = rootProject.file("app/../publish/key.properties") +val keyProperties = Properties() +if (keyPropertiesFile.exists()) { + keyProperties.load(FileInputStream(keyPropertiesFile)) +} + android { namespace = "com.rwadurian.rwa_android_app" compileSdk = flutter.compileSdkVersion @@ -30,11 +40,30 @@ android { versionName = flutter.versionName } + signingConfigs { + create("release") { + if (keyPropertiesFile.exists()) { + keyAlias = keyProperties["keyAlias"] as String + keyPassword = keyProperties["keyPassword"] as String + storeFile = file(keyProperties["storeFile"] as String) + storePassword = keyProperties["storePassword"] as String + } + } + } + buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.getByName("debug") + signingConfig = if (keyPropertiesFile.exists()) { + signingConfigs.getByName("release") + } else { + signingConfigs.getByName("debug") + } + isMinifyEnabled = true + isShrinkResources = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) } } } diff --git a/frontend/mobile-app/android/app/proguard-rules.pro b/frontend/mobile-app/android/app/proguard-rules.pro new file mode 100644 index 00000000..c1b1eaf5 --- /dev/null +++ b/frontend/mobile-app/android/app/proguard-rules.pro @@ -0,0 +1,45 @@ +# Flutter wrapper +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.** { *; } +-keep class io.flutter.plugins.** { *; } + +# Google Play Core (suppress warnings for deferred components) +-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication +-dontwarn com.google.android.play.core.splitinstall.SplitInstallException +-dontwarn com.google.android.play.core.splitinstall.SplitInstallManager +-dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory +-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder +-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest +-dontwarn com.google.android.play.core.splitinstall.SplitInstallSessionState +-dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener +-dontwarn com.google.android.play.core.tasks.OnFailureListener +-dontwarn com.google.android.play.core.tasks.OnSuccessListener +-dontwarn com.google.android.play.core.tasks.Task + +# Keep Kotlin metadata +-keep class kotlin.Metadata { *; } + +# Keep web3dart classes +-keep class org.web3j.** { *; } +-dontwarn org.web3j.** + +# Keep crypto classes +-keep class org.bouncycastle.** { *; } +-dontwarn org.bouncycastle.** + +# Keep Gson classes +-keepattributes Signature +-keepattributes *Annotation* +-keep class com.google.gson.** { *; } + +# Keep R8 from stripping interface information +-keep,allowobfuscation,allowshrinking interface retrofit2.Call +-keep,allowobfuscation,allowshrinking class retrofit2.Response + +# Keep native methods +-keepclasseswithmembernames class * { + native ; +} diff --git a/frontend/mobile-app/android/gradle.properties b/frontend/mobile-app/android/gradle.properties index c587f726..7d2ed05d 100644 --- a/frontend/mobile-app/android/gradle.properties +++ b/frontend/mobile-app/android/gradle.properties @@ -1,2 +1,9 @@ -org.gradle.jvmargs=-Xmx1536m -XX:MaxMetaspaceSize=384m -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParallelGC android.useAndroidX=true + +# Disable parallel builds to reduce memory usage +org.gradle.parallel=false +org.gradle.caching=true + +# Disable lint to reduce memory usage during release build +android.enableR8.fullMode=false