android-gradle-plugin - R8 / Android Gradle Plugin 是否足够智能以保持仅在测试 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
选项,其中包含构建应用程序时生成的映射文件。这样,usedInTest
在运行 R8 之后,测试中的引用将被重命名为应用程序中的实际方法。
对于 R8 本身,我们通过分析 R8 测试来发现测试中使用了 R8 的哪些部分(不在公共 API 上)来实现自动化。由此我们综合了保持规则来保持这一点。然后我们可以在 R8 上运行 R8,然后在该版本的 R8 上运行所有测试——这也是我们最终发布的版本。
推荐阅读
- regex - 使用 RegEx 检查字符串中显式模式的有效性 - 仅由空格分隔的 7 位数字
- azure - 一般如何使用 Azure 身份验证?
- jenkins - 詹金斯 - 只有在有 x 个代理可用时才开始工作
- reactjs - Rect Apexcharts - 条形图上的动态加载图表(柱形图)单击执行功能错误
- spring-boot - Dockerizing springboot应用程序(在容器中)未连接到rabbitmq(在容器中):连接被拒绝
- flutter - 我的服务器将来自客户端的请求注册为多个请求
- c# - 为什么级联 ManualResetEvents 的多次等待会使执行时间增加三倍?
- vue.js - 如何通过计时器从 v-for 中删除?
- c# - 在线托管 json 文件的问题并按 c# HttpClient 发布它们
- javascript - 控制器和服务之间没有传递参数