Android Gradle Build Plugin 4.0.0 & R8 Desugaring 不适用于 API 19

Fra*_*ser 11 android java-8 android-gradle-plugin android-r8 jdk-desugaring

我正在将一个 Android 应用程序从使用 Proguard 的 desugaring 切换到 Android Gradle Build Plugin 4.0.0 中可用的新 R8 desugaring。

我已按照官方文档中详述的步骤启用 Java 8 库脱糖:

gradle.properties

projectJavaVersion = 1.8
android.useAndroidX=true
android.enableJetifier=true
Run Code Online (Sandbox Code Playgroud)

应用程序构建.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"
    ...
}
Run Code Online (Sandbox Code Playgroud)

您可以看到我们至少支持 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()`
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序时,在代码中使用以下 Optional 启动活动时,应用程序崩溃

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$3.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$1.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$2.call(AsyncTask.java:288)
Run Code Online (Sandbox Code Playgroud)

应用程序库

projectJavaVersion = 1.8
android.useAndroidX=true
android.enableJetifier=true
Run Code Online (Sandbox Code Playgroud)

我错过了什么?


在阅读了@sgjesse 的回答后,我们似乎发现了该launch()方法存在的问题,我们做了一些进一步的调查。我可以确认MultiDex.install()之前正在调用launch()

如果我添加一个Optionalin AndroidAppIoHandler,就像这样:

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"
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后我看到:

D/TESTMULTIDEX1( 2826): class j$.util.Optional  class com.example.app.ApplicationBase Optional[com.example.app.ApplicationBase@9d006a00]
Run Code Online (Sandbox Code Playgroud)

这是从 的第一行调用的launch()

如果我将Optionalto添加到方法的下一行launch(),如下所示:

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()`
Run Code Online (Sandbox Code Playgroud)

然后我看到:

java.lang.NoClassDefFoundError: j$.util.Optional
Run Code Online (Sandbox Code Playgroud)

在同一次执行中,打印上面的其他消息后!

Fra*_*ser 1

通过升级到 Android Gradle Build Plugin 4.2.0 解决了这个问题,其中 R8 可以正确脱糖。