简体   繁体   English

Android Kotlin ProGuard 规则错误?

[英]Android Kotlin ProGuard Rules Wrong?

Currently I have a library that is to be consumed by multiple other projects, however I have a problem with the code obfuscation when consuming the.aar in particular with some classes:目前我有一个库供多个其他项目使用,但是在使用.aar 时,我遇到了代码混淆问题,特别是在某些类中:

This one to handle backend responses or asynchronous tasks, etc.这个用于处理后端响应或异步任务等。

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>()
}

And this one to act as a initializer or something like it to the library:而这个充当初始化程序或类似库的东西:

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)
            }
        }
    }
}

The rules I'm using are:我使用的规则是:

#noinspection ShrinkerUnresolvedReference
-keep class com.cross.project.compilation.testlib.response.** { *; }
-keep class com.cross.project.compilation.testlib.LibApp.** { *; }

Currently I have 3 build types and 2 flavors:目前我有 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 {

        }

    }

When I check the decompiled sources for release variants in the consumer project I get:当我检查消费者项目中的发布变体的反编译源时,我得到:

Result gets the < T > stripped from the Success return: 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 */
    }
}

This changes the way something is coded within the variants, from something like this in dev:这改变了在变体中编码的方式,就像在 dev 中这样:

 return when (val response = accountService.getAccountData()) {
            is Result.Success -> ConsumerResult.Success(response.data)
            is Result.ErrorModel -> ConsumerResult.Failure(response.errorModel)
        }

To this:对此:

 return when (val response = accountService.getAccountData()) {
            is Result.Success<*> -> ConsumerResult.Success((response.data as AccountData))
            is Result.ErrorModel -> ConsumerResult.Failure(response.errorModel)
        }

The LibApp class gets removed for some reason. LibApp class 由于某种原因被删除。

I've tried to modify the rules to avoid these issues, but only succeding in keeping the LibApp class by applying the following:我尝试修改规则以避免这些问题,但仅通过应用以下内容成功地保留了 LibApp class:

-keepclasseswithmembers class com.cross.project.compilation.testlib.LibApp {
    public *;
}

-keep @interface kotlin.Metadata {
  *;
}
-keepattributes RuntimeVisibleAnnotations

And also add the @Keep annotation to every level in the class like:并且还在 class 中的每个级别添加 @Keep 注释,例如:

@Keep class LibApp private constructor(
    ...

    @Keep
    companion object {
       ...

        @Keep
        fun init(
        ...

However I've had no luck modifying the rule to keep the generic return of the Result.Success, Any idea of what I'm doing wrong?但是,我没有运气修改规则以保持 Result.Success 的通用返回,知道我做错了什么吗?

As an additional information, I'm using and building with the maven-publish plugin:作为附加信息,我正在使用和构建 maven-publish 插件:

Android Gradle Plugin 4.0.1 Gradle Wrapper 6.1.1 Android Gradle 插件 4.0.1 Gradle 包装器 6.1.1

This problem seems to have appeared after I upgraded from:我从以下位置升级后似乎出现了这个问题:

Android Gradle Plugin 3.6.3 Gradle Wrapper 5.6.4 Android Gradle 插件 3.6.3 Gradle 包装器 5.6.4

The type Nothing in the Result.Error is erased while obfuscating by R8. Result.Error 中的 Nothing 类型在被 R8 混淆时被擦除。 Try to add in build.gradle file the following:尝试在 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 

In proguard file declare the Result type to keep from obfuscation在 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