警告:在库 class android.graphics.Canvas 中找不到引用的方法 'int save(int)'

Warning: can't find referenced method 'int save(int)' in library class android.graphics.Canvas

我在我的一个应用程序中使用了一个不再维护的 Umano 的 AndroidSlidingUpPanel 库:

dependencies {
    // .. redacted
    implementation 'com.sothree.slidinguppanel:library:3.4.0'
}

到目前为止一切正常。今天我尝试将 compileSdkVersion 从 27 更改为 28,并且发布版本开始失败并出现 Proguard 错误(minifyEnabled 设置为 true):

$ ./gradlew clean assembleRelease

> Task :app:transformClassesAndResourcesWithProguardForRelease FAILED
ProGuard, version 6.0.3
Reading input...
// many lines with 'Reading program jar...', redacted
Initializing...
Warning: com.sothree.slidinguppanel.SlidingUpPanelLayout: can't find referenced method 'int save(int)' in library class android.graphics.Canvas
// redacted
Warning: there were 1 unresolved references to library class members.
         You probably need to update the library versions.
         (http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember)

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
> java.io.IOException: Please correct the above warnings first.

BUILD FAILED in 2s

我正在使用 AGP v3.5.0,android.enableR8=false 配置支持 Proguard 而不是 R8。

this issue 中的一条评论建议忽略使用 -dontwarn com.sothree.** 的警告,这确实会导致构建通过。

为什么首先会出现此警告,忽略它是否会产生任何可能的后果?

我们来分析一下警告信息:

Warning: com.sothree.slidinguppanel.SlidingUpPanelLayout: can't find referenced method 'int save(int)' in library class android.graphics.Canvas

库的SlidingUpPanelLayout.java源文件确实includes一个android.graphics.Canvas#save(int)方法调用:

final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);

这个方法是deprecated since API 26, and was marked as @removed in API 28
@removed 注释(连同 @hide 注释)被 doclava 工具使用(生成 public 框架 API 存根的 AOSP 工具,a.k.a . android.jar) 将 public class 方法标记为隐藏。

总结一下:android.graphics.Canvas#save(int) 方法已从 public API 中删除,但它仍然是 runtime/framework 的一部分(另请参阅 this ).在缩小阶段,Proguard 分析字节码,显然无法找到 not-anymore-public-api android.graphics.Canvas#save(int) 方法并显示上述警告。
此方法在 运行 时间内仍然存在,因此可以忽略 Proguard 警告,但有两个注意事项:

  • 由于此方法不再是 public API 的一部分,特定供应商可能会更改框架 classes(即,通过 renaming/removing 此方法)一种会导致 运行 时间错误的方法。
  • 此方法可能会在未来的 AOSP 版本中删除,您可能不会注意到,直到在受影响的设备上调用此方法。

警告忽略规则可以缩小为:

-dontwarn com.sothree.slidinguppanel.SlidingUpPanelLayout

在很长的 运行 中,我建议考虑自己修补这个库(通过更改功能以使用无参数 android.graphics.Canvas#save() 方法),或者如果那不可能 - 迁移到另一种解决方案。