R8 / Android Gradle插件是否足够聪明,可以仅在测试apk中保留所需的库类/方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了R8 / Android Gradle插件是否足够聪明,可以仅在测试apk中保留所需的库类/方法?相关的知识,希望对你有一定的参考价值。

假设我有一个依赖于图书馆的应用程序。该库有两种方法:

  • void usedInApp()
  • void usedInTest()

在应用程序中,我称为usedInApp()。我也有一个调用usedInTest()的测试。如果我运行仪器测试./gradlew app:connectedDebugandroidTest,R8 / AGP是否足够聪明,可以保留usedInTest()或将其删除?

答案

由于应用未使用usedInTest,因此R8会将其删除,并且在运行测试时它将失败,并显示MethodNotFouldError。因此,您需要一个保持规则,以确保测试时usedInTest仍在应用程序中。做到这一点的一种好方法是添加注释,例如KeepForTesting并在应用程序中注释测试需要什么。然后添加此保留规则:

-keep,allowobfuscation class * {
  @KeepForTesting *;
}

注意allowobfuscation调节器。这样就可以将这些测试方法重命名为较短的名称。 Android Studio生成测试时,它将自动将-applymapping选项与在构建应用程序时生成的映射文件一起添加。这样,在运行R8之后,测试中对usedInTest的引用将重命名为应用程序中的实际方法。

对于R8本身,我们通过分析R8测试来发现测试中使用了R8的哪些部分,这些部分不在公共API上,从而实现了自动化。由此我们综合了保持规则以保持这一点。然后,我们可以在R8上运行R8,然后在该版本的R8上运行所有测试-这也是我们最终发布的版本。

以上是关于R8 / Android Gradle插件是否足够聪明,可以仅在测试apk中保留所需的库类/方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上使用 R8 时,是不是需要卸载现有的 Proguard?

Android R8(Proguard) 参数名称已更改(我不想更改我的参数名称)

Android Gradle插件开发基础

Android Gradle插件开发基础

Android Gradle插件开发基础

Android编译优化:D8和R8