| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> ProGuard 在 Android 上的使用姿势,开发这么久这些问题都不会 -> 正文阅读 |
|
[移动开发]ProGuard 在 Android 上的使用姿势,开发这么久这些问题都不会 |
ProGuard 是一个压缩、优化、混淆代码的工具。尽管有很多其他工具供开发者们使用,但是 ProGuard 作为 Android Gradle 构建过程的一部分,已经打包在 SDK 中。 当我们构建应用时,使用 ProGuard 有很多好处。有的开发者更关心混淆这块功能,对我而言最大的用处是打包时移除 dex 中的无用代码。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8PSbPYKs-1630583794712)(https://user-gold-cdn.xitu.io/2018/1/15/160f7822ce7376b5?imageView2/0/w/1280/h/960/ignore-error/1)] 一个 Android 示例应用的空间分布图,源码地址 Topeka sample app。 减少包体积的好处有很多,比如增加用户黏性和满意度,提升下载速度,减少安装时间,以便在终端设备上连接用户,尤其是在新兴市场。当然,有时候您不得不限制您的应用的大小,比如 Instant App 限制大小 4 MB,此时 ProGuard 显得必不可少了。 如果以上还不足以说服您使用 ProGuard,其实移除无用代码和混淆所有名称还有其他更多的优化效果:
但是在您激动的跳起来之前,请先继续阅读下去。当您开启 ProGuard 时,在某些非常微妙的情况下会让您的应用崩溃。虽然有些错误会在构建应用时发生,您能及时发现,但是也有些错误您只能在运行时发现,所以请确保您的应用经过彻底的测试。 如何使用 ProGuard?在您的项目中开启 ProGuard 只需简单到添加如下几行代码在您的主应用模块的
ProGuard 自身的配置已经在另外一个单独的配置文件中完成了。上面的代码中,我给出了 Android Gradle 打包插件中的默认配置1,接下去我会在 在 ProGuard 官网您可以找到一个 使用手册。 在您深入研究这些配置之前,最好先大概理解 ProGuard 是如何工作的和我们为什么要指定一些额外的选项。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QGEkBLpH-1630583794714)(https://user-gold-cdn.xitu.io/2018/1/15/160f7822d9ebd961?imageslim)] 您也可以去观看 part of this Google I/O session Shai Barack 的教学视频。 简单来说,ProGuard 将您项目中的 .class 文件做为输入,然后寻找代码中所有的调用点,计算出代码中所有可达的调用关系图,然后移除剩余的部分(即不可达的代码和那些不会被调用的代码)。 在您读 ProGuard 手册时,您没必要看那些 输入 / 输出的部分,因为这些 Android Gradle 打包插件会替您指定输入源(您和第三方库的代码) 和 Android jar 库(您构建应用时用到的 Android 框架类)。 想要正确配置 ProGuard,最重要的就是让它知道运行时您的哪些代码不应该被移除(如果开启混淆的话,当然也要保持他们的名称不变)。当一些类和方法会被动态访问到时(如使用反射),在某些情况下,ProGuard 在构建调用图时不能正确的决定他们的「生死」,导致这些代码被错误的移除掉。当您只从 XML 资源引用您的代码会时(通常使用底层的反射),这个情况也会发生。 在一次 Android 典型的构建过程中,AAPT(处理资源的工具)会生成一个额外的 ProGuard 规则文件。它会为 Android 应用添加一些特别的 keep 规则,所以您在 Android Manifest.xml 中记录的 Activities、Services、BroadcastReceivers 和 ContentProviders 会保持不动. 这就是为什么在上面动图中 AAPT 也会 keep 住所有在 XML 布局文件使用到的 View 类(和它们的构造函数)和其他一些类,如在过渡动画资源中引用到的过渡类。 您可以在构建后直接看这个 AAPT 生成的配置文件,位置是: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFpXJWYG-1630583794715)(https://user-gold-cdn.xitu.io/2018/1/15/160f782370cc310b?imageView2/0/w/1280/h/960/ignore-error/1)] 在构建时 AAPT 生成的一个示例 ProGuard 配置文件 我会在本文后面章节中讨论更多关于 keep 规则,但是在那之前我们最好先学一下在以下情况时应该怎么做: 当 ProGuard 打断了您的构建在您可以测试是否开启 ProGuard 后所有代码在运行时都能正常工作前,您需要先构建您的应用。不幸的是,ProGuard 可能会发现一些引用的类缺失,并给予告警,导致您的构建失败。 修复这个问题的关键是仔细观察构建时输出的消息,理解这些警告的内容并定位他们。通常的途径是修正您的依赖或者在您的 ProGuard 配置中添加 -dontwarn 规则。 这些警告的一个原因就是,您的构建路径中没有加入需要依赖的 JARs,如使用了 provided (仅编译时)依赖。而有时候,在 Android 上这些代码的依赖在运行时并不会被真正的调用。让我们看一个真实的例子。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fVe5bNYA-1630583794717)(https://user-gold-cdn.xitu.io/2018/1/15/160f78238e566d41?imageView2/0/w/1280/h/960/ignore-error/1)] 一个项目依赖 OkHttp 3.8.0 构建时的消息。 OkHttp 库在 3.8.0 版本的类中添加了新的注解( 因为我们知道这些注解类在运行时不会被使用,我们可以通过在 ProGuard 配置中添加 -dontwarn 规则来安全地忽略掉这些警告,如 在 OkHttp 文档中加入这些规则:
您应该经历过类似的过程,在输出消息中看到这些警告,然后重新构建直到构建通过。重要的是去理解为什么您会收到这些警告以及您在构建时是否真的缺少这些类。 现在您可能会尝试使用 -ignorewarnings 选项直接忽略所有的警告,但这通常不是个好注意。在某些情况下,ProGuard 的警告确实有助于您发现闪退的罪魁祸首和关于您配置上的其他问题。 您可能需要了解一下 Progard的 notes (优先级低于警告的消息),它可以帮您发现一些反射相关的问题。虽然它不会打断您的构建,但是在运行时可能会闪退。这会在下面的场景中发生: 当 ProGuard 移除过多的类在某些情况下,ProGuard 并不知道一个类或者方法被使用了,例如这个类仅在反射时被使用或者仅在 XML 中被引用。为了阻止这样的代码被移除或混淆,您应当在 ProGuard 配置中指定额外 keep 规则。这取决于作为应用开发者的你,需要去发现哪些部分代码有问题并提供必要的规则。 当运行时发生了 您有很多选项来配置您的 ProGuard:
我建议您从 ProGuard 的这篇 class specification syntax 开始熟悉,此文讨论了上述所有的 keep 规则和前一段讨论到的 -dontwarn 选项。另外这三个 keep 规则也各有一个不同的版本支持仅保留混淆(重命名),不保留压缩。您可以在 ProGuard 官网的表格看一下概览。 作为一个可选的方案来写 ProGuard 规则,您可以直接在某个不想被混淆和移除的类、方法、属性上添加 @Keep 注解。注意,如果这样做的话,您需要把 Android 默认的 ProGuard 配置加入到您的构建中。 APK Analyzer 和 ProGuardAndroid Studio 集成的 APK Analyzer 可以帮您看到哪些类被 ProGuard 移除了并支持为它们生成 keep 规则。当您构建 APK 时开启了 ProGuard,那么会额外输出一些文件在 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CGoHABfd-1630583794718)(https://user-gold-cdn.xitu.io/2018/1/15/160f7823a8e0ef80?imageslim)] 加载 ProGuard 映射文件到 APK Analyzer 可以看到 DEX 视图中更多的信息 当您加载了映射文件到 APK Analyzer时(点击 “Load Proguard mappings… “ 按钮), 您可以在 DEX 视图树中看到一些额外功能:
当 ProGuard 移除过少的类所有应用都可以使用 Android 内置的 ProGuard 的一些安全的默认规则,如保留 如果您希望 ProGuard 移除所有未使用的代码,您应当避免 keep 规则写的太宽泛,如加入通配符匹配整个包,而是使用类相关的匹配规则或者使用上面提及的 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5i7vv19-1630583794719)(https://user-gold-cdn.xitu.io/2018/1/15/160f782444355418?imageView2/0/w/1280/h/960/ignore-error/1)] 使用 如果您实在不确定为什么 ProGuard 没有移除您期望它移除的代码,,您可以添加 -whyareyoukeeping 选项至 ProGuard 配置文件中,然后重新构建您的应用。在构建输出中,您会看到是什么调用链决定了 ProGuard 保留这些代码。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ptvrOzqp-1630583794720)(https://user-gold-cdn.xitu.io/2018/1/15/160f78245a621ba6?imageView2/0/w/1280/h/960/ignore-error/1)] 在 APK Analyzer 中追踪是什么在 DEX 中 keep 住了这些类和方法 学习分享在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了 很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘 如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。 2021最新上万页的大厂面试真题 七大模块学习资料:如NDK模块开发、Android框架体系架构… 只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》 由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。定能改变你现在的状态呢! CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》 由于文章内容比较多,篇幅不允许,部分未展示内容以截图方式展示 。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 1:47:37- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |