这些警告的一个原因就是,您的构建路径中没有加入需要依赖的 JARs,如使用了 provided (仅编译时)依赖。而有时候,在 Android 上这些代码的依赖在运行时并不会被真正的调用。让我们看一个真实的例子。
一个项目依赖 OkHttp 3.8.0 构建时的消息。
OkHttp 库在 3.8.0 版本的类中添加了新的注解(javax.annotation.Nullable
)。但是因为它们使用了编译时的依赖,所以这些注解在最终构建时不会被打包进去(哪怕应用显式的依赖了 com.google.code.findbugs:jsr305
),因此 ProGuard 会抱怨 缺失了这些类.
因为我们知道这些注解类在运行时不会被使用,我们可以通过在 ProGuard 配置中添加 -dontwarn 规则来安全地忽略掉这些警告,如 在 OkHttp 文档中加入这些规则:
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
您应该经历过类似的过程,在输出消息中看到这些警告,然后重新构建直到构建通过。重要的是去理解为什么您会收到这些警告以及您在构建时是否真的缺少这些类。
现在您可能会尝试使用 -ignorewarnings 选项直接忽略所有的警告,但这通常不是个好注意。在某些情况下,ProGuard 的警告确实有助于您发现闪退的罪魁祸首和关于您配置上的其他问题。
您可能需要了解一下 Progard的 notes (优先级低于警告的消息),它可以帮您发现一些反射相关的问题。虽然它不会打断您的构建,但是在运行时可能会闪退。这会在下面的场景中发生:
当 ProGuard 移除过多的类
在某些情况下,ProGuard 并不知道一个类或者方法被使用了,例如这个类仅在反射时被使用或者仅在 XML 中被引用。为了阻止这样的代码被移除或混淆,您应当在 ProGuard 配置中指定额外 keep 规则。这取决于作为应用开发者的你,需要去发现哪些部分代码有问题并提供必要的规则。
当运行时发生了 ClassNotFoundException
或 MethodNotFoundException
异常意味着您肯定缺失了某些类或者方法,也许是 ProGuard 移除了他们,又或者是因为错误配置依赖而导致无法找到他们。所以生产环境的构建(开启 ProGuard 时)一定要注重彻底的测试并正视这些错误。
您有很多选项来配置您的 ProGuard:
- **keep **— 保留所有匹配的类和方法
- **keepclassmembers **— 当且仅当它们的类因为其他的原因被保留时(被其他调用点引用到或者被其他的规则 keep 住),keep 住指定的一些成员
- **keepclasseswithmembers **— 当且仅当所有的成员在匹配的类中存在时,会 keep 住 这些类和它的成员
我建议您从 ProGuard 的这篇 class specification syntax 开始熟悉,此文讨论了上述所有的 keep 规则和前一段讨论到的 -dontwarn 选项。另外这三个 keep 规则也各有一个不同的版本支持仅保留混淆(重命名),不保留压缩。您可以在 ProGuard 官网的表格看一下概览。
作为一个可选的方案来写 ProGuard 规则,您可以直接在某个不想被混淆和移除的类、方法、属性上添加 @Keep 注解。注意,如果这样做的话,您需要把 Android 默认的 ProGuard 配置加入到您的构建中。
APK Analyzer 和 ProGuard
Android Studio 集成的 APK Analyzer 可以帮您看到哪些类被 ProGuard 移除了并支持为它们生成 keep 规则。当您构建 APK 时开启了 ProGuard,那么会额外输出一些文件在 <app_module>/build/outputs/mapping/
目录下。这些文件包含了移除代码的信息、混淆的映射关系。
加载 ProGuard 映射文件到 APK Analyzer 可以看到 DEX 视图中更多的信息
当您加载了映射文件到 APK Analyzer时(点击 “Load Proguard mappings… “ 按钮), 您可以在 DEX 视图树中看到一些额外功能:
- 所有的名字都是混淆前的(即您可以看到原始的名字)
- 被 ProGuard 配置规则 kept 的包,类,方法和属性会显示成粗体
- 您可以开启 “Show removed nodes” 选项来看任何被 ProGuard 移除的内容(字体上会有删除线)。右击树上的一个节点可以让您生成一个 keep 规则以便您粘贴到您的配置文件中。
当 ProGuard 移除过少的类
所有应用都可以使用 Android 内置的 ProGuard 的一些安全的默认规则,如保留 View
的 getter 和 setter 方法,因为他们通常会被反射来访问,以及其他一些普通的方法和类都不会被移除。 这在许多情况下可以时您的应用避免崩溃的发生,但是这些配置并不是 100% 适合您的应用。您可以移除掉默认的 ProGuard 文件而使用您自己的。
如果您希望 ProGuard 移除所有未使用的代码,您应当避免 keep 规则写的太宽泛,如加入通配符匹配整个包,而是使用类相关的匹配规则或者使用上面提及的 @Keep
注解。
使用 -whyareyoukeeping <class-specification>
选项来观察为什么这些类没有被移除。
如果您实在不确定为什么 ProGuard 没有移除您期望它移除的代码,,您可以添加 -whyareyoukeeping 选项至 ProGuard 配置文件中,然后重新构建您的应用。在构建输出中,您会看到是什么调用链决定了 ProGuard 保留这些代码。
在 APK Analyzer 中追踪是什么在 DEX 中 keep 住了这些类和方法
另一种方法不那么精准,但在任何应用都不需要重新构建和额外的工作量。那就是在 APK Analyzer 中打开 DEX 文件,然后右击您关注的类、方法。选择 “Find usages” 您将看到引用链,这也许会引导您了解哪部分代码使用指定的类、方法从而阻止了它被移除。
ProGuard 和 混淆后的堆栈
我之前提及到,在构建过程中 ProGuard 会在处理类文件时输出映射关系和日志文件。当您需要保留构建产物时,您应当保存好这些文件和 APK 在一起。这些映射文件不能被其他的构建所使用,而只会在与它们一起生成的 APK 配合使用时才能确保正确。有了这些映射关系,您才能有效地 debug 用户设备的发生的崩溃。否则太难去定位问题了,因为名字都混淆过了。
上传 APK 对应的 ProGuard 映射文件至 Google Play 控制台,从而获得混淆前的堆栈信息。
您在 Google Play 控制台发布混淆后的生产 APK时,记得为每个版本上传对应的映射文件。这样的话当您看 ANRs & crashes 页面时,上报的堆栈都会现实真实的类名、方法名和行号而不是缩短的混淆后的那些。
关于 ProGuard 和 第三方库
就像您有责任为您自己的代码提供 keep 规则一样,那些第三方库的作者们也有义务向您提供必要的混淆规则配置来避免开启 Proguard 导致的构建失败或者应用崩溃。
有些项目简单地在他们的文档或者 README 上提及了必要的混淆规则,所以您需要复制粘贴这些规则到您的主 ProGuard 配置文件中。不过有个更好的方法,第三方库的维护者们如果发布的库是 AAR ,那么可以指定规则打包在 AAR 中并会在应用构建时自动暴露给构建系统,通过添加下面几行代码到库模块的 build.gradle
文件中:
release { //or your own build type
consumerProguardFiles ‘consumer-proguard.txt’
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
Android高级架构师
由于篇幅问题,我呢也将自己当前所在技术领域的各项知识点、工具、框架等汇总成一份技术路线图,还有一些架构进阶视频、全套学习PDF文件、面试文档、源码笔记做整理一份资料。
需要的朋友可以**私信【学习】**我分享给你,希望里面的资料可以给你们一个更好的学习参考。
或者直接点击下面链接免费获取
- 330页PDF Android学习核心笔记(内含上面8大板块)
-
Android学习的系统对应视频
-
Android进阶的系统对应学习资料
- Android BAT部分大厂面试题(有解析)
好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。
]
- Android BAT部分大厂面试题(有解析)
[外链图片转存中…(img-O6MphBXM-1710846908421)]
好了,以上便是今天的分享,希望为各位朋友后续的学习提供方便。觉得内容不错,也欢迎多多分享给身边的朋友哈。