From 6d18af496b5262a93d4067b50ef3909249df6a00 Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Tue, 23 Jun 2026 14:57:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E5=BA=93=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=20isMinifyEnabled=20=E4=BF=AE=E5=A4=8D=20Duplicate=20?= =?UTF-8?q?class=20=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Android 库模块开启 isMinifyEnabled=true 时,R8 各自独立混淆, 将内部类重命名为 a.a / a.b 等短名打进 AAR;多个 AAR 合并到 App 时产生 Duplicate class 冲突。 修复:删除全部 7 个库模块 buildTypes.release 中的 isMinifyEnabled, 混淆由 App 的 R8 统一完成。将 proguard-rules.pro 中的保留规则 (manifest 注册类、反射调用入口、dontwarn)合并进各模块的 consumer-rules.pro 随 AAR 打包。 Co-Authored-By: Claude Sonnet 4.6 --- sdk-bugcollect/build.gradle.kts | 9 --------- sdk-bugcollect/consumer-rules.pro | 11 +++++++++++ sdk-bugcollect/proguard-rules.pro | 24 +----------------------- sdk-core/build.gradle.kts | 9 --------- sdk-core/consumer-rules.pro | 5 +++++ sdk-core/proguard-rules.pro | 18 +----------------- sdk-im/build.gradle.kts | 9 --------- sdk-im/proguard-rules.pro | 13 +------------ sdk-license/build.gradle.kts | 9 --------- sdk-license/consumer-rules.pro | 8 ++++++++ sdk-license/proguard-rules.pro | 17 +---------------- sdk-push/build.gradle.kts | 9 --------- sdk-push/consumer-rules.pro | 11 +++++++++++ sdk-push/proguard-rules.pro | 27 +-------------------------- sdk-update/build.gradle.kts | 9 --------- sdk-update/proguard-rules.pro | 13 +------------ sdk-webview/build.gradle.kts | 9 --------- sdk-webview/consumer-rules.pro | 8 +++++++- sdk-webview/proguard-rules.pro | 13 +------------ 19 files changed, 49 insertions(+), 182 deletions(-) diff --git a/sdk-bugcollect/build.gradle.kts b/sdk-bugcollect/build.gradle.kts index 59aa3d6..99bf336 100644 --- a/sdk-bugcollect/build.gradle.kts +++ b/sdk-bugcollect/build.gradle.kts @@ -13,15 +13,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } publishing { singleVariant("release") { withSourcesJar() } } diff --git a/sdk-bugcollect/consumer-rules.pro b/sdk-bugcollect/consumer-rules.pro index a12c880..e2ba34b 100644 --- a/sdk-bugcollect/consumer-rules.pro +++ b/sdk-bugcollect/consumer-rules.pro @@ -6,3 +6,14 @@ -keep public class com.xuqm.sdk.bugcollect.LogLevel { public *; } -keep public class com.xuqm.sdk.bugcollect.Breadcrumb { public *; } -keep public class com.xuqm.sdk.bugcollect.FunnelTracker { public *; } +-keep public class com.xuqm.sdk.bugcollect.IssueEvent { *; } +-keep public class com.xuqm.sdk.bugcollect.LogEvent { *; } + +# ContentProvider: class name referenced in AndroidManifest — must not be renamed +-keep class com.xuqm.sdk.bugcollect.internal.BugCollectInitProvider + +-keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod + +-keepclassmembers class com.xuqm.sdk.bugcollect.** { + @com.google.gson.annotations.SerializedName ; +} diff --git a/sdk-bugcollect/proguard-rules.pro b/sdk-bugcollect/proguard-rules.pro index 7378586..4e8ed23 100644 --- a/sdk-bugcollect/proguard-rules.pro +++ b/sdk-bugcollect/proguard-rules.pro @@ -1,23 +1 @@ -# BugCollect object: accessed via reflection from sdk-webview (captureError, INSTANCE) --keep class com.xuqm.sdk.bugcollect.BugCollect { - public *; - static ; -} - -# Public types passed to / returned from BugCollect public API --keep public class com.xuqm.sdk.bugcollect.Breadcrumb { public *; } --keep public class com.xuqm.sdk.bugcollect.LogLevel { public *; } --keep public class com.xuqm.sdk.bugcollect.IssueEvent { *; } --keep public class com.xuqm.sdk.bugcollect.LogEvent { *; } --keep public class com.xuqm.sdk.bugcollect.FunnelTracker { public *; } - -# ContentProvider: class name referenced in AndroidManifest — must not be renamed --keep class com.xuqm.sdk.bugcollect.internal.BugCollectInitProvider - --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# Gson field names in log payloads --keepclassmembers class com.xuqm.sdk.bugcollect.** { - @com.google.gson.annotations.SerializedName ; -} --dontwarn com.xuqm.sdk.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-core/build.gradle.kts b/sdk-core/build.gradle.kts index fd6e706..f2335c3 100644 --- a/sdk-core/build.gradle.kts +++ b/sdk-core/build.gradle.kts @@ -19,15 +19,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-core/consumer-rules.pro b/sdk-core/consumer-rules.pro index dccd889..9e12c10 100644 --- a/sdk-core/consumer-rules.pro +++ b/sdk-core/consumer-rules.pro @@ -20,7 +20,12 @@ @com.google.gson.annotations.SerializedName ; } +# ── Kotlinx serialization ───────────────────────────────────────────────────── +-keepclassmembers @kotlinx.serialization.Serializable class ** { *; } +-keep class kotlinx.serialization.** { *; } + # ── Retrofit / OkHttp (belt-and-suspenders; they ship their own rules) ──────── -keepattributes Signature -keepattributes *Annotation* -keepattributes Exceptions +-keepattributes InnerClasses, EnclosingMethod diff --git a/sdk-core/proguard-rules.pro b/sdk-core/proguard-rules.pro index aa8a2a9..4e8ed23 100644 --- a/sdk-core/proguard-rules.pro +++ b/sdk-core/proguard-rules.pro @@ -1,17 +1 @@ -# sdk-core is the base dependency for all other SDK modules. -# Renaming its classes would break the cross-module class references at runtime -# (each module's R8 sees sdk-core's minified output as classpath). -# Strategy: dead-code elimination only, no renaming. --keep class com.xuqm.sdk.** { *; } - -# Kotlin & annotation metadata (required by kotlinx.serialization and Compose) --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# Kotlinx serialization --keepclassmembers @kotlinx.serialization.Serializable class ** { *; } --keep class kotlinx.serialization.** { *; } - -# Gson field names in network models --keepclassmembers class com.xuqm.sdk.** { - @com.google.gson.annotations.SerializedName ; -} +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-im/build.gradle.kts b/sdk-im/build.gradle.kts index 073dc97..e6e6313 100644 --- a/sdk-im/build.gradle.kts +++ b/sdk-im/build.gradle.kts @@ -17,15 +17,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-im/proguard-rules.pro b/sdk-im/proguard-rules.pro index e98098d..4e8ed23 100644 --- a/sdk-im/proguard-rules.pro +++ b/sdk-im/proguard-rules.pro @@ -1,12 +1 @@ -# Public API --keep public class com.xuqm.sdk.im.ImSDK { public *; } --keep public class com.xuqm.sdk.im.model.** { public *; } --keep public interface com.xuqm.sdk.im.listener.** { public *; } - --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# IM message payloads use Gson --keepclassmembers class com.xuqm.sdk.im.** { - @com.google.gson.annotations.SerializedName ; -} --dontwarn com.xuqm.sdk.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-license/build.gradle.kts b/sdk-license/build.gradle.kts index c013c88..700cc9a 100644 --- a/sdk-license/build.gradle.kts +++ b/sdk-license/build.gradle.kts @@ -18,15 +18,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-license/consumer-rules.pro b/sdk-license/consumer-rules.pro index 3bb56c3..b7a7348 100644 --- a/sdk-license/consumer-rules.pro +++ b/sdk-license/consumer-rules.pro @@ -12,6 +12,14 @@ @com.google.gson.annotations.SerializedName ; } +# ContentProvider: class name referenced in AndroidManifest — must not be renamed +-keep class com.xuqm.sdk.license.internal.LicenseInitializerProvider + +# ── Kotlinx serialization ───────────────────────────────────────────────────── +-keepclassmembers @kotlinx.serialization.Serializable class ** { *; } +-keep class kotlinx.serialization.** { *; } + # ── Retrofit / OkHttp ──────────────────────────────────────────────────────── -keepattributes Signature -keepattributes *Annotation* +-keepattributes InnerClasses, EnclosingMethod diff --git a/sdk-license/proguard-rules.pro b/sdk-license/proguard-rules.pro index 15f4f45..4e8ed23 100644 --- a/sdk-license/proguard-rules.pro +++ b/sdk-license/proguard-rules.pro @@ -1,16 +1 @@ -# Public API --keep public class com.xuqm.sdk.license.LicenseSDK { public *; } --keep public interface com.xuqm.sdk.license.LicenseCallback { public *; } --keep public class com.xuqm.sdk.license.LicenseConfig { public *; } --keep public class com.xuqm.sdk.license.LicenseResult { public *; } --keep public class com.xuqm.sdk.license.model.** { public *; } - -# ContentProvider: class name referenced in AndroidManifest — must not be renamed --keep class com.xuqm.sdk.license.internal.LicenseInitializerProvider - --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# Kotlinx serialization (used by this module) --keepclassmembers @kotlinx.serialization.Serializable class ** { *; } --keep class kotlinx.serialization.** { *; } --dontwarn com.xuqm.sdk.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-push/build.gradle.kts b/sdk-push/build.gradle.kts index 0c2003f..9783712 100644 --- a/sdk-push/build.gradle.kts +++ b/sdk-push/build.gradle.kts @@ -20,15 +20,6 @@ android { manifestPlaceholders["XUQM_HONOR_APP_ID"] = "" } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-push/consumer-rules.pro b/sdk-push/consumer-rules.pro index 89d0231..dd1ca31 100644 --- a/sdk-push/consumer-rules.pro +++ b/sdk-push/consumer-rules.pro @@ -26,3 +26,14 @@ -keepattributes Signature -keepattributes *Annotation* -keepattributes Exceptions +-keepattributes InnerClasses, EnclosingMethod + +# ── Optional deps (compileOnly) — suppress R8 missing-class warnings ────────── +-dontwarn com.google.android.gms.** +-dontwarn com.google.firebase.** +-dontwarn com.huawei.** +-dontwarn com.hihonor.** +-dontwarn io.github.hebeiliang.** +-dontwarn com.umeng.** +-dontwarn com.heytap.** +-dontwarn com.vivo.** diff --git a/sdk-push/proguard-rules.pro b/sdk-push/proguard-rules.pro index 0fa7070..4e8ed23 100644 --- a/sdk-push/proguard-rules.pro +++ b/sdk-push/proguard-rules.pro @@ -1,26 +1 @@ -# Public API entry point --keep public class com.xuqm.sdk.push.PushSDK { public *; } --keep public class com.xuqm.sdk.push.model.** { public *; } --keep public class com.xuqm.sdk.push.PushNotificationChannelManager { public *; } - -# Service / Receiver classes registered in AndroidManifest — must NOT be renamed --keep class com.xuqm.sdk.push.fcm.XuqmFirebaseMessagingService --keep class com.xuqm.sdk.push.honor.XuqmHonorPushService --keep class com.xuqm.sdk.push.huawei.XuqmHuaweiPushService --keep class com.xuqm.sdk.push.xiaomi.XuqmXiaomiPushReceiver --keep class com.xuqm.sdk.push.vivo.XuqmVivoPushReceiver - --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod --dontwarn com.xuqm.sdk.** - -# Firebase / GMS: compileOnly — transitive classes may be missing from classpath --dontwarn com.google.android.gms.** --dontwarn com.google.firebase.** - -# Vendor push SDKs: compileOnly / optional transitive deps --dontwarn com.huawei.** --dontwarn com.hihonor.** --dontwarn io.github.hebeiliang.** --dontwarn com.umeng.** --dontwarn com.heytap.** --dontwarn com.vivo.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-update/build.gradle.kts b/sdk-update/build.gradle.kts index 3200e73..756a511 100644 --- a/sdk-update/build.gradle.kts +++ b/sdk-update/build.gradle.kts @@ -17,15 +17,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-update/proguard-rules.pro b/sdk-update/proguard-rules.pro index 63271a3..4e8ed23 100644 --- a/sdk-update/proguard-rules.pro +++ b/sdk-update/proguard-rules.pro @@ -1,12 +1 @@ -# Public API --keep public class com.xuqm.sdk.update.UpdateSDK { public *; } --keep public interface com.xuqm.sdk.update.UpdateListener { public *; } --keep public class com.xuqm.sdk.update.model.** { public *; } - --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# Gson model fields in update info payload --keepclassmembers class com.xuqm.sdk.update.** { - @com.google.gson.annotations.SerializedName ; -} --dontwarn com.xuqm.sdk.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro. diff --git a/sdk-webview/build.gradle.kts b/sdk-webview/build.gradle.kts index 463f4ca..2acb445 100644 --- a/sdk-webview/build.gradle.kts +++ b/sdk-webview/build.gradle.kts @@ -18,15 +18,6 @@ android { consumerProguardFiles("consumer-rules.pro") } - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/sdk-webview/consumer-rules.pro b/sdk-webview/consumer-rules.pro index 81393d5..b0b21dd 100644 --- a/sdk-webview/consumer-rules.pro +++ b/sdk-webview/consumer-rules.pro @@ -1 +1,7 @@ -# Keep module rules intentionally empty for now. +# All webview classes are public API consumed directly by app code +-keep public class com.xuqm.sdk.webview.** { public *; } + +# XWebViewActivity is registered in AndroidManifest — must not be renamed +-keep class com.xuqm.sdk.webview.XWebViewActivity + +-keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod diff --git a/sdk-webview/proguard-rules.pro b/sdk-webview/proguard-rules.pro index 172af79..4e8ed23 100644 --- a/sdk-webview/proguard-rules.pro +++ b/sdk-webview/proguard-rules.pro @@ -1,12 +1 @@ -# All webview classes are public API consumed directly by app code --keep public class com.xuqm.sdk.webview.** { public *; } - -# XWebViewActivity is registered in AndroidManifest — must not be renamed --keep class com.xuqm.sdk.webview.XWebViewActivity - -# Compose @Composable functions require annotation and signature retention --keepattributes *Annotation*, Signature, InnerClasses, EnclosingMethod - -# sdk-core internal classes (auth/network) appear "missing" after sdk-core's R8 pass -# when both modules build in the same Gradle invocation; suppress to allow compilation --dontwarn com.xuqm.sdk.** +# Library modules do not use isMinifyEnabled. Rules are in consumer-rules.pro.