Android Gradle 构建插件 4.0.0 和 R8 脱糖在 API 19 上不起作用
Android Gradle Build Plugin 4.0.0 & R8 Desugaring not working on API 19
我正在将 Android 应用程序从使用 Proguard 的脱糖转换为 Android Gradle 构建插件 4.0.0 中提供的新 R8 脱糖。
我已按照 in the official documentation 中详细说明的步骤启用 Java 8 库脱糖:
gradle.properties
projectJavaVersion = 1.8
android.useAndroidX=true
android.enableJetifier=true
应用build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
buildToolsVersion '29.0.2'
compileSdkVersion 29
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility projectJavaVersion
targetCompatibility projectJavaVersion
}
kotlinOptions {
jvmTarget = projectJavaVersion
}
defaultConfig {
multiDexEnabled true
minSdkVersion 19
targetSdkVersion 23
applicationId = 'com.example.app'
}
buildTypes {
release {
...
minifyEnabled true
}
debug {
debuggable true
minifyEnabled true
}
}
}
dependencies {
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.10"
...
}
您可以看到我们至少支持 API 19。没有构建错误(使用Gradle 6.1.1),但有以下警告:
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$Function$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparing($-vivified-$.java.util.function.Function)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToLongFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingLong($-vivified-$.java.util.function.ToLongFunction)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToDoubleFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingDouble($-vivified-$.java.util.function.ToDoubleFunction)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToIntFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingInt($-vivified-$.java.util.function.ToIntFunction)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$EntryIterator.class:
Type `j$.$r8$wrapper$java$util$function$Consumer$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.concurrent.ConcurrentHashMap$EntryIterator.forEachRemaining($-vivified-$.java.util.function.Consumer)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$stream$Stream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.Stream java.util.concurrent.ConcurrentHashMap$CollectionView.parallelStream()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$Spliterator$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.Spliterator java.util.concurrent.ConcurrentHashMap$CollectionView.spliterator()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$function$Predicate$-V-WRP` was not found, it is required for default or static interface methods desugaring of `boolean java.util.concurrent.ConcurrentHashMap$CollectionView.removeIf($-vivified-$.java.util.function.Predicate)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/DesugarCollections$SynchronizedMap.class:
Type `j$.$r8$wrapper$java$util$function$BiFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.DesugarCollections$SynchronizedMap.replaceAll($-vivified-$.java.util.function.BiFunction)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/DesugarCollections$SynchronizedMap.class:
Type `j$.$r8$wrapper$java$util$function$BiConsumer$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.DesugarCollections$SynchronizedMap.forEach($-vivified-$.java.util.function.BiConsumer)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$IntStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.IntStream java.util.concurrent.ThreadLocalRandom.ints()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$LongStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.LongStream java.util.concurrent.ThreadLocalRandom.longs()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$DoubleStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.DoubleStream java.util.concurrent.ThreadLocalRandom.doubles(long)`
Warning: Type `java.util.OptionalConversions` was not found, it is required for default or static interface methods desugaring of `java.util.OptionalLong j$.$r8$wrapper$java$util$stream$LongStream$-WRP.findAny()`
Warning: Type `java.util.LongSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.LongSummaryStatistics j$.$r8$wrapper$java$util$stream$LongStream$-WRP.summaryStatistics()`
Warning: Type `java.util.IntSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.IntSummaryStatistics j$.$r8$wrapper$java$util$stream$IntStream$-WRP.summaryStatistics()`
Warning: Type `java.util.DoubleSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.DoubleSummaryStatistics j$.$r8$wrapper$java$util$stream$DoubleStream$-WRP.summaryStatistics()`
当我 运行 应用程序启动 activity 并在代码中使用以下可选时,应用程序崩溃
I/ApplicationBase: Testing Java 8
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.app.DEV, PID: 8265
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NoClassDefFoundError: j$.util.Optional
at com.example.app.ApplicationBase.launch(ApplicationBase.java:251)
at com.example.app.LaunchTask.doInBackground(LaunchTask.java:19)
at com.example.app.LaunchTask.doInBackground(LaunchTask.java:6)
at android.os.AsyncTask.call(AsyncTask.java:288)
ApplicationBase.java
import androidx.multidex.MultiDexApplication
import java.util.Optional;
public class ApplicationBase extends MultiDexApplication implements LaunchTask.Launcher {
@SuppressLint("NewApi")
@Override
public void launch() throws IOException {
IOHandler ioHandler = new AndroidAppIOHandler(getApplicationContext());
Logger.i(TAG, "Testing Java 8");
Optional.of("xyz").ifPresent(__ -> Logger.i(TAG, "Good"));
Logger.i(TAG, "Tested Java 8");
...
}
...
}
我错过了什么?
阅读 后,似乎发现 launch()
方法存在问题,我们进行了进一步调查。我可以确认 MultiDex.install()
在 launch()
.
之前被调用
如果我在 AndroidAppIoHandler
中添加一个 Optional
,像这样:
public AndroidAppIOHandler(Context context) {
this.context = context;
final Optional<Context> context1 = Optional.of(context);
Log.d("TESTMULTIDEX1", context1.getClass() + " " + context1.get().getClass() + " " + context1.toString());
}
然后我看到:
D/TESTMULTIDEX1( 2826): class j$.util.Optional class com.example.app.ApplicationBase Optional[com.example.app.ApplicationBase@9d006a00]
从launch()
的第一行开始调用。
如果我将 Optional
添加到 launch()
方法的下一行,如下所示:
public void launch() throws IOException {
IOHandler ioHandler = new AndroidAppIOHandler(getApplicationContext());
final Optional<IOHandler> ioHandler1 = Optional.of(ioHandler);
...
然后我看到:
java.lang.NoClassDefFoundError: j$.util.Optional
在同一执行中,在打印上面的其他消息后!
如果崩溃仅出现在 API 级别 19 的设备上,原因可能是在使用脱糖类型之前未调用 MultiDex.install
。
java.util.Optional
的实现(在脱糖库中称为 j$.util.Optional
)在一个单独的 DEX 文件中。在不支持原生 multi dex(在 API 级别 21 中添加)的设备上,必须先调用 MultiDex.install
才能使用脱糖类型。在 MultiDexApplication
中,对 MultiDex.install
的调用在 attachBaseContext
中。如果在 MultiDex.install
之前调用 launch
方法,您将看到 NoClassDefFoundError
.
我遇到了一个非常相似的问题,就我而言,结果是 Android Gradle 插件中的 a bug。长话短说,AGP 在不同的 DEX 文件中生成一些相同的包装器 类,这些包装器在旧的 Android 版本上会造成 Dalvik/ART。而且问题只出现在调试版本上,因为 R8/ProGuard 在发布版本中删除了 类 的重复数据。
那个问题有a workaround:
buildscript {
repositories {
maven {
url "https://storage.googleapis.com/r8-releases/raw/master" // NOTICE 'master' here!
}
}
dependencies {
classpath 'com.android.tools:r8:f03be11f11b8405b69876d05337e917a5519e52a' // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
希望这对您有所帮助。
我在仍然支持 Android 4.1 的旧版应用程序中遇到了同样的问题。在创建示例项目并尝试重现错误后,我发现了问题(或错误?)。
不幸的是,Android 4.4 或更低版本的设备似乎无法使用任何 Java 8 class 或将由 Core Library Desugaring 在 onCreate 方法中触及的接口应用程序。
这似乎是一个奇怪的多重索引issue/bug。
我尝试了以下方法:
class CoreApplication : MultiDexApplication() {
override fun attachBaseContext(base: Context?) {
//adding the new GMS causes to many Methods in APK, therefore configure Application as MultiDex
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
Optional.of("TEst")
}
}
这将导致您提到的崩溃:
03-22 18:36:09.231 657-657/com.plauzeware.CoreLibraryDesugeringCrashOnAndroidKitkat E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.plauzeware.CoreLibraryDesugeringCrashOnAndroidKitkat, PID: 657
java.lang.NoClassDefFoundError: j$.util.Optional
at com.plauzeware.corelibrarydesugeringcrashonandroidkitkat.CoreApplication.onCreate(Application.kt:17)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1030)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4409)
at android.app.ActivityThread.access00(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1270)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
但是当我将对 Optional 的调用包装在一个助手中时 class
class Loader {
companion object {
fun load() {
Optional.of("TEst")
}
}
}
并在我的 onCreate 函数中调用它
class CoreApplication : MultiDexApplication() {
override fun attachBaseContext(base: Context?) {
//adding the new GMS causes to many Methods in APK, therefore configure Application as MultiDex
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
Loader.load()
}
}
它会起作用的。我认为这是一个错误,我将提交错误报告并使用 Link 更新此答案。
因为 multidexing 问题也触及像 Iterable
这样的基本界面,所以解决这些错误真的很痛苦。特别是因为我们仍然使用 OrmLite,它会一直使用 Iterable
。
我已经添加了我的代码以供参考我的 Github
更新:
Here 是错误报告的 link。
这已通过升级到 Android Gradle 构建插件 4.2.0 解决,其中 R8 正确脱糖。
我正在将 Android 应用程序从使用 Proguard 的脱糖转换为 Android Gradle 构建插件 4.0.0 中提供的新 R8 脱糖。
我已按照 in the official documentation 中详细说明的步骤启用 Java 8 库脱糖:
gradle.properties
projectJavaVersion = 1.8
android.useAndroidX=true
android.enableJetifier=true
应用build.gradle
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
buildToolsVersion '29.0.2'
compileSdkVersion 29
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility projectJavaVersion
targetCompatibility projectJavaVersion
}
kotlinOptions {
jvmTarget = projectJavaVersion
}
defaultConfig {
multiDexEnabled true
minSdkVersion 19
targetSdkVersion 23
applicationId = 'com.example.app'
}
buildTypes {
release {
...
minifyEnabled true
}
debug {
debuggable true
minifyEnabled true
}
}
}
dependencies {
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.10"
...
}
您可以看到我们至少支持 API 19。没有构建错误(使用Gradle 6.1.1),但有以下警告:
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$Function$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparing($-vivified-$.java.util.function.Function)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToLongFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingLong($-vivified-$.java.util.function.ToLongFunction)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToDoubleFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingDouble($-vivified-$.java.util.function.ToDoubleFunction)`
Warning in synthesized for lambda desugaring:
Type `j$.$r8$wrapper$java$util$function$ToIntFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `java.util.Comparator java.time.chrono.-$$Lambda$AbstractChronology$j22w8kHhJoqCd56hhLQK1G0VLFw.thenComparingInt($-vivified-$.java.util.function.ToIntFunction)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$EntryIterator.class:
Type `j$.$r8$wrapper$java$util$function$Consumer$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.concurrent.ConcurrentHashMap$EntryIterator.forEachRemaining($-vivified-$.java.util.function.Consumer)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$stream$Stream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.Stream java.util.concurrent.ConcurrentHashMap$CollectionView.parallelStream()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$Spliterator$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.Spliterator java.util.concurrent.ConcurrentHashMap$CollectionView.spliterator()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ConcurrentHashMap$CollectionView.class:
Type `j$.$r8$wrapper$java$util$function$Predicate$-V-WRP` was not found, it is required for default or static interface methods desugaring of `boolean java.util.concurrent.ConcurrentHashMap$CollectionView.removeIf($-vivified-$.java.util.function.Predicate)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/DesugarCollections$SynchronizedMap.class:
Type `j$.$r8$wrapper$java$util$function$BiFunction$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.DesugarCollections$SynchronizedMap.replaceAll($-vivified-$.java.util.function.BiFunction)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/DesugarCollections$SynchronizedMap.class:
Type `j$.$r8$wrapper$java$util$function$BiConsumer$-V-WRP` was not found, it is required for default or static interface methods desugaring of `void java.util.DesugarCollections$SynchronizedMap.forEach($-vivified-$.java.util.function.BiConsumer)`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$IntStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.IntStream java.util.concurrent.ThreadLocalRandom.ints()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$LongStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.LongStream java.util.concurrent.ThreadLocalRandom.longs()`
Warning in /Users/username/.gradle/caches/modules-2/files-2.1/com.android.tools/desugar_jdk_libs/1.0.4/961afbdb3d41eebfb63b8c8ccdc97453b869964e/desugar_jdk_libs-1.0.4.jar:java/util/concurrent/ThreadLocalRandom.class:
Type `j$.$r8$wrapper$java$util$stream$DoubleStream$-WRP` was not found, it is required for default or static interface methods desugaring of `$-vivified-$.java.util.stream.DoubleStream java.util.concurrent.ThreadLocalRandom.doubles(long)`
Warning: Type `java.util.OptionalConversions` was not found, it is required for default or static interface methods desugaring of `java.util.OptionalLong j$.$r8$wrapper$java$util$stream$LongStream$-WRP.findAny()`
Warning: Type `java.util.LongSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.LongSummaryStatistics j$.$r8$wrapper$java$util$stream$LongStream$-WRP.summaryStatistics()`
Warning: Type `java.util.IntSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.IntSummaryStatistics j$.$r8$wrapper$java$util$stream$IntStream$-WRP.summaryStatistics()`
Warning: Type `java.util.DoubleSummaryStatisticsConversions` was not found, it is required for default or static interface methods desugaring of `java.util.DoubleSummaryStatistics j$.$r8$wrapper$java$util$stream$DoubleStream$-WRP.summaryStatistics()`
当我 运行 应用程序启动 activity 并在代码中使用以下可选时,应用程序崩溃
I/ApplicationBase: Testing Java 8
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.app.DEV, PID: 8265
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.NoClassDefFoundError: j$.util.Optional
at com.example.app.ApplicationBase.launch(ApplicationBase.java:251)
at com.example.app.LaunchTask.doInBackground(LaunchTask.java:19)
at com.example.app.LaunchTask.doInBackground(LaunchTask.java:6)
at android.os.AsyncTask.call(AsyncTask.java:288)
ApplicationBase.java
import androidx.multidex.MultiDexApplication
import java.util.Optional;
public class ApplicationBase extends MultiDexApplication implements LaunchTask.Launcher {
@SuppressLint("NewApi")
@Override
public void launch() throws IOException {
IOHandler ioHandler = new AndroidAppIOHandler(getApplicationContext());
Logger.i(TAG, "Testing Java 8");
Optional.of("xyz").ifPresent(__ -> Logger.i(TAG, "Good"));
Logger.i(TAG, "Tested Java 8");
...
}
...
}
我错过了什么?
阅读 launch()
方法存在问题,我们进行了进一步调查。我可以确认 MultiDex.install()
在 launch()
.
如果我在 AndroidAppIoHandler
中添加一个 Optional
,像这样:
public AndroidAppIOHandler(Context context) {
this.context = context;
final Optional<Context> context1 = Optional.of(context);
Log.d("TESTMULTIDEX1", context1.getClass() + " " + context1.get().getClass() + " " + context1.toString());
}
然后我看到:
D/TESTMULTIDEX1( 2826): class j$.util.Optional class com.example.app.ApplicationBase Optional[com.example.app.ApplicationBase@9d006a00]
从launch()
的第一行开始调用。
如果我将 Optional
添加到 launch()
方法的下一行,如下所示:
public void launch() throws IOException {
IOHandler ioHandler = new AndroidAppIOHandler(getApplicationContext());
final Optional<IOHandler> ioHandler1 = Optional.of(ioHandler);
...
然后我看到:
java.lang.NoClassDefFoundError: j$.util.Optional
在同一执行中,在打印上面的其他消息后!
如果崩溃仅出现在 API 级别 19 的设备上,原因可能是在使用脱糖类型之前未调用 MultiDex.install
。
java.util.Optional
的实现(在脱糖库中称为 j$.util.Optional
)在一个单独的 DEX 文件中。在不支持原生 multi dex(在 API 级别 21 中添加)的设备上,必须先调用 MultiDex.install
才能使用脱糖类型。在 MultiDexApplication
中,对 MultiDex.install
的调用在 attachBaseContext
中。如果在 MultiDex.install
之前调用 launch
方法,您将看到 NoClassDefFoundError
.
我遇到了一个非常相似的问题,就我而言,结果是 Android Gradle 插件中的 a bug。长话短说,AGP 在不同的 DEX 文件中生成一些相同的包装器 类,这些包装器在旧的 Android 版本上会造成 Dalvik/ART。而且问题只出现在调试版本上,因为 R8/ProGuard 在发布版本中删除了 类 的重复数据。
那个问题有a workaround:
buildscript {
repositories {
maven {
url "https://storage.googleapis.com/r8-releases/raw/master" // NOTICE 'master' here!
}
}
dependencies {
classpath 'com.android.tools:r8:f03be11f11b8405b69876d05337e917a5519e52a' // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
希望这对您有所帮助。
我在仍然支持 Android 4.1 的旧版应用程序中遇到了同样的问题。在创建示例项目并尝试重现错误后,我发现了问题(或错误?)。
不幸的是,Android 4.4 或更低版本的设备似乎无法使用任何 Java 8 class 或将由 Core Library Desugaring 在 onCreate 方法中触及的接口应用程序。
这似乎是一个奇怪的多重索引issue/bug。
我尝试了以下方法:
class CoreApplication : MultiDexApplication() {
override fun attachBaseContext(base: Context?) {
//adding the new GMS causes to many Methods in APK, therefore configure Application as MultiDex
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
Optional.of("TEst")
}
}
这将导致您提到的崩溃:
03-22 18:36:09.231 657-657/com.plauzeware.CoreLibraryDesugeringCrashOnAndroidKitkat E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.plauzeware.CoreLibraryDesugeringCrashOnAndroidKitkat, PID: 657
java.lang.NoClassDefFoundError: j$.util.Optional
at com.plauzeware.corelibrarydesugeringcrashonandroidkitkat.CoreApplication.onCreate(Application.kt:17)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1030)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4409)
at android.app.ActivityThread.access00(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1270)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
但是当我将对 Optional 的调用包装在一个助手中时 class
class Loader {
companion object {
fun load() {
Optional.of("TEst")
}
}
}
并在我的 onCreate 函数中调用它
class CoreApplication : MultiDexApplication() {
override fun attachBaseContext(base: Context?) {
//adding the new GMS causes to many Methods in APK, therefore configure Application as MultiDex
super.attachBaseContext(base)
MultiDex.install(this)
}
override fun onCreate() {
super.onCreate()
Loader.load()
}
}
它会起作用的。我认为这是一个错误,我将提交错误报告并使用 Link 更新此答案。
因为 multidexing 问题也触及像 Iterable
这样的基本界面,所以解决这些错误真的很痛苦。特别是因为我们仍然使用 OrmLite,它会一直使用 Iterable
。
我已经添加了我的代码以供参考我的 Github
更新:
Here 是错误报告的 link。
这已通过升级到 Android Gradle 构建插件 4.2.0 解决,其中 R8 正确脱糖。