[英]Android Kotlin ProGuard Rules Wrong?
目前我有一个库供多个其他项目使用,但是在使用.aar 时,我遇到了代码混淆问题,特别是在某些类中:
这个用于处理后端响应或异步任务等。
sealed class Result<out T : Any> {
open class Success<out T : Any>(val data: T) : Result<T>()
open class Error(val error: ErrorModel) : Result<Nothing>()
}
而这个充当初始化程序或类似库的东西:
class LibApp private constructor(
val appContext: Context
) {
companion object {
@JvmStatic lateinit var instance: LibApp
private set
fun init(
appContext: Context
) {
if (this::instance.isInitialized.not()) {
instance = LibApp(appContext)
}
}
}
}
我使用的规则是:
#noinspection ShrinkerUnresolvedReference
-keep class com.cross.project.compilation.testlib.response.** { *; }
-keep class com.cross.project.compilation.testlib.LibApp.** { *; }
目前我有 3 种构建类型和 2 种风格:
buildTypes {
release {
debuggable false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
releaseDebug{
debuggable true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug{
debuggable true
minifyEnabled false
}
}
flavorDimensions "libFlavors"
productFlavors {
dev {
}
prod {
}
}
当我检查消费者项目中的发布变体的反编译源时,我得到:
Result 从 Success 返回中获取 <T>:
public sealed class Result<out T : kotlin.Any> private constructor() {
public open class Error public constructor(error: com.cross.project.compilation.testlib.response.ErrorModel) : com.cross.project.compilation.testlib.response.Result {
public final val error: com.cross.project.compilation.testlib.response.ErrorModel /* compiled code */
}
public open class Success<out T : kotlin.Any> public constructor(data: T) : com.cross.project.compilation.testlib.response.Result {
public final val data: T /* compiled code */
}
}
这改变了在变体中编码的方式,就像在 dev 中这样:
return when (val response = accountService.getAccountData()) {
is Result.Success -> ConsumerResult.Success(response.data)
is Result.ErrorModel -> ConsumerResult.Failure(response.errorModel)
}
对此:
return when (val response = accountService.getAccountData()) {
is Result.Success<*> -> ConsumerResult.Success((response.data as AccountData))
is Result.ErrorModel -> ConsumerResult.Failure(response.errorModel)
}
LibApp class 由于某种原因被删除。
我尝试修改规则以避免这些问题,但仅通过应用以下内容成功地保留了 LibApp class:
-keepclasseswithmembers class com.cross.project.compilation.testlib.LibApp {
public *;
}
-keep @interface kotlin.Metadata {
*;
}
-keepattributes RuntimeVisibleAnnotations
并且还在 class 中的每个级别添加 @Keep 注释,例如:
@Keep class LibApp private constructor(
...
@Keep
companion object {
...
@Keep
fun init(
...
但是,我没有运气修改规则以保持 Result.Success 的通用返回,知道我做错了什么吗?
作为附加信息,我正在使用和构建 maven-publish 插件:
Android Gradle 插件 4.0.1 Gradle 包装器 6.1.1
我从以下位置升级后似乎出现了这个问题:
Android Gradle 插件 3.6.3 Gradle 包装器 5.6.4
Result.Error 中的 Nothing 类型在被 R8 混淆时被擦除。 尝试在 build.gradle 文件中添加以下内容:
buildscript {
repositories {
// other repos are omitted
maven { url 'https://storage.googleapis.com/r8-releases/raw' }
}
dependencies {
classpath 'com.android.tools:r8:2.1.68'
// other dependencies are omitted
在 proguard 文件中声明 Result 类型以防止混淆
-keep class [path_to_class].Result { *; }
-keep class [path_to_class].Result$** { *; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.