【发布时间】:2018-07-17 12:32:16
【问题描述】:
在将依赖项更新到最新版本后,由于缺少接口实现,我们在发布版本中遇到了运行时崩溃
java.lang.IncompatibleClassChangeError:
Class 'com.mypackage.app.data.cache.query.user.QueryUserFollowersCountById'
does not implement interface 'com.mypackage.app.data.cache.query.Query'
in call to 'java.lang.String[] com.mypackage.app.data.cache.query.Query.c()'
(declaration of 'com.mypackage.app.data.cache.database.util.Db'
appears in /data/app/com.mypackage.app-2/base.apk:classes2.dex)
经过两天的调试,我们认为该问题与 Proguard 在其收缩阶段剥离“实现查询”有关。接口本身在数百个其他类中使用时保留,仅在 3 个类中丢失。我们还发现一些 RxJava Func0 和 Action0 接口以同样的方式被剥离,同样在极少数地方。因此,该应用在 95% 的屏幕上都能完美运行,但在缺少接口实现的地方显然会崩溃。
- 我们正在使用 Gradle 构建工具版本 3.1.3,但也尝试使用 3.3.0-alpha03,还尝试禁用 D8,因此它不应该是构建工具问题(Proguard 版本 5.3.3 和 6.0.3 也一样在这种情况下以同样的方式)
- 将 Dagger2 从 2.11 版本升级到 2.12 或更高版本时出现此问题,因此它可能与应用中的字段/方法/类等的数量有关
- 即使使用 -dontoptimize,问题仍然存在,我们已经阅读了 Proguard 文档并启用/禁用了几乎所有相关标志
- 通过将 minifyEnabled 设置为 false 或对 Proguard 使用 -dontshrink 标志来解决此问题
- 该应用程序使用 Multidex,使用 Dagger 2.11 和 Dagger 2.12 构建最终都有 3 个 classes.dex 文件。在这两种情况下,有问题的接口和实现都在同一个 .dex 文件中。
- 例如,同一个包中有 5 个文件实现了 Query,其中 3 个文件在生成的字节码中有接口,但 2 个文件没有。所以它不应该与文件的放置位置有关。
使用 Dagger 2.11 或 -dontshrink 构建时的字节码
.class public Lcom/mypackage/app/data/cache/query/user/QueryUserFollowersCountById;
.super Ljava/lang/Object;
.source "SourceFile"
# interfaces
.implements Lcom/mypackage/app/data/cache/query/Query;
# annotations
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Object;",
"Lcom/mypackage/app/data/cache/query/Query<",
"Ljava/lang/Integer;",
">;"
}
.end annotation
......
使用 Dagger 2.12 或更高版本构建时的字节码
.class public Lcom/mypackage/app/data/cache/query/user/QueryUserFollowersCountById;
.super Ljava/lang/Object;
.source "SourceFile"
# annotations
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Object;"
}
.end annotation
......
我们显然希望使用最新版本的 Dagger2,并且还想通过 Proguard 不断缩小和优化我们的代码。
- 如何确保 Proguard 不会剥离 implements 接口语句?
- 或者如何在 Proguard 收缩步骤中添加日志记录/调试?
【问题讨论】:
-
嘿,你找到解决办法了吗?我也在为同样的问题苦苦挣扎……
-
嘿@definera,很遗憾没有。听到这个问题直到现在 R8 和更新版本的 Dagger 2 都存在,我感到非常难过。
标签: android android-gradle-plugin proguard dagger-2 android-proguard