繁体   English   中英

Android Kotlin ProGuard 规则错误?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM