标签: android-r8

Android build fails with R8

Build is failing with the following error upon enabling R8 on android studio 3.4-RC3. Build is successful if android.enableR8=false

Undefined value encountered during compilation. This is typically caused by invalid dex input that uses a register that is not define on all control-flow paths leading to the use.

What is this undefined value and how do I fix this error?

> Task :app:transformClassesAndResourcesWithR8ForStageInternal FAILED
D8: Undefined value encountered during compilation. This is typically caused by invalid dex input that uses …
Run Code Online (Sandbox Code Playgroud)

android gradle android-studio gradle-kotlin-dsl android-r8

5
推荐指数
2
解决办法
913
查看次数

使用 R8 混淆应用程序导致超出 GC 开销限制

我刚刚将 Android Studio 更新到v3.4.1

现在我无法在设置 minifyEnabled 时生成签名的应用程序 true

我知道现在默认的代码压缩器是R8。正如日志所说,这就是问题所在。如果 minifyEnabled 设置为 ,我可以毫无问题地生成签名的应用程序false

这发生在我所有的项目中。

继续运行:

  • 视窗 10 64 位
  • 内存 8 GB
  • 英特尔 i5 2320 处理器

我该如何解决?谢谢你


构建.gradle

buildTypes {
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
Run Code Online (Sandbox Code Playgroud)

proguard-rules.pro

-dontobfuscate
Run Code Online (Sandbox Code Playgroud)

完整日志

org.gradle.internal.exceptions.LocationAwareException: Execution failed for task ':app:transformClassesAndResourcesWithR8ForRelease'.
    at org.gradle.initialization.exception.DefaultExceptionAnalyser.transform(DefaultExceptionAnalyser.java:99)
    at org.gradle.initialization.exception.DefaultExceptionAnalyser.collectFailures(DefaultExceptionAnalyser.java:65)
    at org.gradle.initialization.exception.MultipleBuildFailuresExceptionAnalyser.transform(MultipleBuildFailuresExceptionAnalyser.java:39)
    at org.gradle.initialization.exception.StackTraceSanitizingExceptionAnalyser.transform(StackTraceSanitizingExceptionAnalyser.java:29)
    at org.gradle.initialization.DefaultGradleLauncher.finishBuild(DefaultGradleLauncher.java:174)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:165)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:134)
    at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:58)
    at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:55)
    at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:82)
    at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:75)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:183)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40) …
Run Code Online (Sandbox Code Playgroud)

obfuscation android android-studio android-r8

5
推荐指数
1
解决办法
1643
查看次数

当代码被 R8 缩小时,Android 生命周期观察者不会触发

当我使用minifyEnabled=true生命周期观察者构建代码时,不会触发任何事件。

lifecycle.addObserver(object : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    @Keep
    fun anyEvent(source: LifecycleOwner, event: Lifecycle.Event) {
        // Never triggers
        Timber.i("Source=%s, event=%s", source, event)
    }
})
Run Code Online (Sandbox Code Playgroud)

androidx.lifecycle:lifecycle版本2.2.0-rc01(以前的版本也可能会受到影响)。

compileSdkVersion28,我正在 Android 10 (API29) 模拟器上进行测试。

android proguard android-lifecycle android-r8 androidx

5
推荐指数
1
解决办法
576
查看次数

使用 AndroidX 时,proguard-android-optimize.txt 中的“@Keep 支持注释”规则是否仍然适用?

通常proguard-android-optimize.txt作为 proguard 文件来应用。

proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
Run Code Online (Sandbox Code Playgroud)

然而,当我浏览完内容后proguard-android-optimize.txt

...

-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * {*;}

-keepclasseswithmembers class * {
    @android.support.annotation.Keep <methods>;
}

-keepclasseswithmembers class * …
Run Code Online (Sandbox Code Playgroud)

android proguard android-r8 androidx

5
推荐指数
1
解决办法
4344
查看次数

R8 完整模式的真正作用是什么(积极优化)?

R8正式文件说要激活额外的优化我必须在插入此gradle.properties文件:

android.enableR8.fullMode=true
Run Code Online (Sandbox Code Playgroud)

文档说,为了使应用程序工作,我必须设置一些保留规则,但没有关于它如何工作以及它执行哪些操作的详细信息:

由于额外的优化使 R8 的行为与 ProGuard 不同,它们可能需要您包含额外的 ProGuard 规则以避免运行时问题。例如,假设您的代码通过 Java 反射 API 引用了一个类。默认情况下,R8 假定您打算在运行时检查和操作该类的对象——即使您的代码实际上没有这样做——并且它会自动保留该类及其静态初始化程序。

然而,当使用“完整模式”时,R8 不会做出这个假设,如果 R8 断言您的代码在运行时从不使用该类,它会从您的应用程序的最终 DEX 中删除该类。也就是说,如果您想保留类及其静态初始值设定项,您需要在规则文件中包含一个保留规则来做到这一点。

文档建议的常见问题解答的链接仅说明了这一点:

R8全模式

在完整模式下,R8 执行更积极的优化,这意味着可能需要额外的 ProGuard 配置规则。本节重点介绍使用完整模式时遇到的一些常见问题。

实际效果如何android.enableR8.fullMode

非常感谢!

obfuscation optimization android shrink android-r8

5
推荐指数
1
解决办法
1766
查看次数

R8 将抽象类的“受保护”方法更改为“公共”方法,不带 -allowaccessmodification 标志

我对 R8 有疑问。在MyLib我有公共摘要MyLibsClass中,我有受保护的方法。从 R8 的魔法中和之后MyChildClass扩展,所有受保护的方法(包括受保护的抽象)都更改为公共方法,当然,我在尝试覆盖受保护的抽象方法时遇到了问题。MyLibsClassMyAppMyLibsClassMyChildClass"attempting to assign weaker access privileges ('protected'); was 'public')

附加信息

gradle-6.0.1

MyLib的build.gradle

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
}
Run Code Online (Sandbox Code Playgroud)

proguard-rules.pro

-keep class com.example.mylib.*{
    public protected *; }

-keep class com.example.mylib.*$*{
    public protected *; }
Run Code Online (Sandbox Code Playgroud)

有人遇到过此类问题或知道解决此问题的方法吗?

android proguard android-studio android-r8

5
推荐指数
1
解决办法
1680
查看次数

R8 缩小:多次定义类型

在构建签名发布 APK 时,我收到以下错误:

.gradle/caches/transforms-2/files-2.1/532a317ccd54c8ae4f622faeb8b534a9/jetified-wordup-core-0.2.1-runtime.jar:de/codereddev/wordup/database/WordDao_Impl$5.class,
Type de.codereddev.wordup.database.WordDao_Impl$5 is defined multiple times:
/home/codered_dev/.gradle/caches/transforms-2/files-2.1/532a317ccd54c8ae4f622faeb8b534a9/jetified-wordup-core-0.2.1-runtime.jar:de/codereddev/wordup/database/WordDao_Impl$5.class,
/home/codered_dev/MySoundboardApp/app/build/intermediates/javac/release/classes/de/codereddev/wordup/database/WordDao_Impl$5.class
Run Code Online (Sandbox Code Playgroud)

这个 Room DAO 定义来自我自己创建的

查看.jar文件我可以找到这个:

在此处输入图片说明

这仅在发布时发生。我仍然可以毫无问题地构建和运行调试。

不幸的是我找不到错误。希望这里的任何人都可以给我一个提示。

我首先假设这可能是因为该库包含 Room 数据库的标准定义,而我使用该库的应用程序包含其自己的自定义定义,其中包含相同的 DAO。所以注释处理器可能会处理 DAO 两次。但我无法正确检查。

如果知道很重要:我也在使用 Koin 进行依赖注入。

android android-room android-r8

5
推荐指数
1
解决办法
983
查看次数

Kotlin 数据类的 toString 方法的混淆

我在我的应用程序中到处使用 Kotlin 数据类。

我在编译时使用 R8。

我有一个安全要求,即生成的toString方法不能包含原始属性名称。目前,生成的方法包含纯文本形式的整个类属性名称及其混淆值名称。

public String toString() {
    return "MyClass(id="+this.f1231msd+", password="+this.fj92313+")");
}
Run Code Online (Sandbox Code Playgroud)

我有几个选择,但我想看看是否还有其他我没有找到的选择。

  1. 我检查了 Proguard 的源代码,发现这个类toString方法中使用了混淆名称。如果 R8 这样做但似乎没有这样做,这将是完美的。
  2. toString用空字符串手动覆盖每个数据类的方法。
  3. 为我编写第 2 步的 R8 规则
  4. 创建一个编译时注释以返回一个空字符串 toString

还有其他选择吗?

android kotlin android-r8

5
推荐指数
1
解决办法
279
查看次数

R8 在构建时无声地崩溃

我收到以下警告 - 构建 Android 版本时出错。

WARNING:R8: Unexpected error during rewriting of Kotlin metadata for class 'androidx.lifecycle.LifecycleController$observer$1':
com.android.tools.r8.internal.sG: lateinit property function has not been initialized
    at com.android.tools.r8.internal.Xn.a(SourceFile:302)
    at com.android.tools.r8.internal.Kn.a(SourceFile:49)
    at com.android.tools.r8.internal.Kn.a(SourceFile:24)
    at com.android.tools.r8.utils.V.a(SourceFile:36)
    at com.android.tools.r8.utils.V.a(SourceFile:41)
    at com.android.tools.r8.utils.V.a(SourceFile:35)
    at java.base/java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1448)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Run Code Online (Sandbox Code Playgroud)

通常我不会太注意警告。

但是我们在发布中遇到了一个相关的生命周期错误(比如观察者根本不起作用)。

我试过-keepclasseswithmembers class androidx.lifecycle.LifecycleController.** { *; }没有运气。

android proguard android-r8

5
推荐指数
1
解决办法
224
查看次数

Android R8 找不到方法

我有两个问题。无论哪种方式,我都无法构建发布 apk。当我禁用 R8(更喜欢 proguard)时,构建会永远持续下去(有时会崩溃,引用“内存不足:java 堆空间”),当我启用 R8 时,我收到以下错误:

Unable to find method 'com.android.tools.r8.CompatProguardCommandBuilder.setProguardSeedsConsumer(Lcom/android/tools/r8/StringConsumer;)Lcom/android/tools/r8/R8Command$Builder;'.
Run Code Online (Sandbox Code Playgroud)

我的项目级 build.gradle:

buildscript {
    repositories {
        google()
        mavenLocal()
        jcenter()
        maven { url "https://maven.google.com" }
        maven { url 'http://storage.googleapis.com/r8-releases/raw' }
    }
    dependencies {
        classpath 'com.android.tools:r8:1.5.68'
        classpath 'com.android.tools.build:gradle:3.6.0-alpha09'
        classpath 'com.google.gms:google-services:4.3.1'
        classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.3'
    }
}

allprojects {
    tasks.withType(JavaCompile) {
        options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked"
    }
    repositories {
        google()
        mavenLocal()
        jcenter()
        maven { url "https://maven.google.com" }
    }
    apply plugin: "com.jfrog.artifactory"
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)

而我的项目模块 build.gradle:

apply plugin: …
Run Code Online (Sandbox Code Playgroud)

android android-gradle-plugin android-r8

4
推荐指数
1
解决办法
1175
查看次数