如何解决多个 D8 警告:未找到 <Class X>,默认或静态接口方法需要对 <Class Y> 进行脱糖?

Posted

技术标签:

【中文标题】如何解决多个 D8 警告:未找到 <Class X>,默认或静态接口方法需要对 <Class Y> 进行脱糖?【英文标题】:How to resolve multiple D8 warnings: <Class X> was not found, it is required for default or static interface methods desugaring <Class Y>? 【发布时间】:2019-03-17 21:39:49 【问题描述】:

android Gradle 插件从 3.1.4 升级到 3.2.x 后,我收到多个警告,例如:

D8: Type `com.google.gson.reflect.TypeToken` was not found, it is required for default or static interface methods desugaring of `com.google.gson.reflect.TypeToken org.springframework.http.converter.json.GsonHttpMessageConverter.getTypeToken(java.lang.reflect.Type)`
D8: Type `com.squareup.okhttp.MediaType` was not found, it is required for default or static interface methods desugaring of `com.squareup.okhttp.MediaType org.springframework.http.client.OkHttpClientHttpRequest.getContentType(org.springframework.http.HttpHeaders)`
D8: Type `org.apache.http.impl.client.HttpClients` was not found, it is required for default or static interface methods desugaring of `void org.springframework.http.client.HttpComponentsClientHttpRequestFactory.<init>()`
D8: Interface `org.apache.http.HttpEntity` not found. It's needed to make sure desugaring of `org.springframework.http.client.HttpComponentsStreamingClientHttpRequest$StreamingHttpEntity` is correct. Desugaring will assume that this interface has no default method.
D8: Type `org.conscrypt.Conscrypt` was not found, it is required for default or static interface methods desugaring of `okhttp3.internal.platform.Platform okhttp3.internal.platform.ConscryptPlatform.buildIfSupported()`
...

项目正在使用 Java 1.8 源代码兼容性 (lambdas),看起来警告来自 Android gradle 类 dexer,它已在 AGP 3.2.0 中默认启用。

    我试图在proguard-rules.pro 中使用以下几行来抑制这些警告,但似乎没有任何效果。

    -dontwarn com.google.gson.reflect.TypeToken
    -keep class com.google.gson.reflect.TypeToken  *; 
    -dontwarn org.apache.http.**
    -keep class com.squareup.okhttp.**  *; 
    -dontwarn com.squareup.okhttp.**
    -keep class org.springframework.http.client.**  *; 
    -dontwarn org.springframework.http.client.**
    

    让警告消失的唯一方法是在build.gradle 文件中将minifyEnableduseProguard 设置为false

    我尝试了 AGP 3.3.0-alpha13 和新的 AGP 3.2.1,但没有成功。

您可以使用来自https://github.com/mdawid/D8WarningTest的示例项目克隆存储库

【问题讨论】:

问题已上报,可在issuetracker.google.com/issues/118842646追踪 【参考方案1】:

更新:该问题已在 Android Gradle 插件 3.5.0-beta05 中得到修复(请参阅问题:Ability to selectively suppress warnings during D8 desugaring)。


对于 Android Gradle 插件 3.2.1 - 3.4.1,请使用以下解决方法:

来自Android Gradle插件3.2.1 changelog:

现在默认启用 D8 脱糖功能。

所以你应该禁用 D8 去糖(在项目的 gradle.properties 文件中):

android.enableD8.desugaring=false

如果你使用 R8:

R8 是一个新的代码压缩和混淆工具,它取代了 ProGuard。您可以通过在项目的 gradle.properties 文件中包含以下内容来开始使用 R8 的预览版:

android.enableR8 = true

使用 R8 禁用脱糖(在项目的 gradle.properties 文件中):

android.enableR8.desugaring=false

【讨论】:

当我尝试启用 R8 android.enableR8=true > 警告:选项设置“android.enableR8=true”是实验性的,不受支持。当前的默认值为 'false',gradle 仍然会给出警告。 当我通过设置属性 android.enableD8.desugaring=false 在 D8 中禁用脱糖时,警告消失了。您还可以通过设置属性android.enableR8.desugaring=false 来禁用 R8 中的脱糖功能。 @kuelye 请编辑您的答案以阐明应启用/禁用哪些设置。那我会接受你的回答。谢谢! 禁用 R8 不是解决方案,您只是压制问题并误导开发人员使用 google 正在推向主流的工具。【参考方案2】:

我认为这是因为这个类是用Java8编写的,但是项目是用Java7编译的。所以我更新如下:

compileOptions 
     sourceCompatibility JavaVersion.VERSION_1_8
     targetCompatibility JavaVersion.VERSION_1_8
 

这解决了我的问题

【讨论】:

如果您查看示例项目,您会发现sourceCompatibility 已经设置为Java 8。这种情况下没有任何区别。

以上是关于如何解决多个 D8 警告:未找到 <Class X>,默认或静态接口方法需要对 <Class Y> 进行脱糖?的主要内容,如果未能解决你的问题,请参考以下文章

如何找到引发警告的未命名组件

Oracle导出警告&ldquo;EXP-00003: 未找到段 (0,0) 的存储定义&rdquo;解决

如何在 jquery 数据表中找到空表或未找到匹配项时添加自定义警告消息

未处理的承诺警告。如何解决?

如何在 WebStorm 中对抗大量未解决的变量警告?

DB2 LUW 版本 10.5.0.10 - 在存储过程中获取警告(未找到)行