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 Studio 更新到v3.4.1
现在我无法在设置 minifyEnabled 时生成签名的应用程序 true
我知道现在默认的代码压缩器是R8。正如日志所说,这就是问题所在。如果 minifyEnabled 设置为 ,我可以毫无问题地生成签名的应用程序false。
这发生在我所有的项目中。
继续运行:
我该如何解决?谢谢你
构建.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) 当我使用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(以前的版本也可能会受到影响)。
这compileSdkVersion是28,我正在 Android 10 (API29) 模拟器上进行测试。
通常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) 在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?
非常感谢!
我对 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)
有人遇到过此类问题或知道解决此问题的方法吗?
在构建签名发布 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 进行依赖注入。
我在我的应用程序中到处使用 Kotlin 数据类。
我在编译时使用 R8。
我有一个安全要求,即生成的toString方法不能包含原始属性名称。目前,生成的方法包含纯文本形式的整个类属性名称及其混淆值名称。
public String toString() {
return "MyClass(id="+this.f1231msd+", password="+this.fj92313+")");
}
Run Code Online (Sandbox Code Playgroud)
我有几个选择,但我想看看是否还有其他我没有找到的选择。
toString方法中使用了混淆名称。如果 R8 这样做但似乎没有这样做,这将是完美的。toString用空字符串手动覆盖每个数据类的方法。toString还有其他选择吗?
我收到以下警告 - 构建 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.** { *; }没有运气。
我有两个问题。无论哪种方式,我都无法构建发布 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 ×10
android-r8 ×10
proguard ×4
androidx ×2
obfuscation ×2
android-room ×1
gradle ×1
kotlin ×1
optimization ×1
shrink ×1