编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.崩溃捕获设计实践
  • 02.崩溃治理优化总结
  • 03.Native崩溃治理实践
  • 04.ANR监控设计实践
  • 05.CPU消耗优化实践
  • 06.卡顿监控设计实践
  • 07.卡顿治理优化实践
  • 08.网络分析与优化实践
  • 09.线程优化实践操作
  • 10.高性能图片优化方案
  • 11.OOM异常优化实践
  • 12.内存监控优化方案
  • 13.内存治理优化实践
  • 14.FPS监测设计实践
  • 15.进程优化设计实践
  • 16.App启动优化实践
  • 17.App页面UI优化实践
  • 18.App稳定性专项实践
  • 19.App瘦身优化实践
  • 20.常见代码优化实践
  • 21.移动端防抓包实践
  • 22.App磁盘沙盒实践
  • 23.Ping工具开发实践
  • 24.Gradle构建优化实践
  • 25.CodeReview实践总结

19.App瘦身优化实践

目录介绍

  • 1.APK组成
    • 1.1 APK组成部分
  • 2.如何压缩优化apk
    • 2.1 资源方面
    • 2.2 代码方面
  • 3.其他操作
    • 3.1 lint检查
    • 3.2 如何检测哪些图片未被使用
    • 3.3 如何检测哪些无效代码
  • 4.对比前后

1.APK组成

1.1 APK组成部分

  • 如下所示
    • res:包含未编译到的资源 resources.arsc,主要有图片资源文件;
    • classes.dex:包含以Dalvik / ART虚拟机可理解的DEX文件格式编译的类;
    • assets:包含应用可以使用AssetManager对象检索的应用资源;
    • lib/:包含特定于处理器软件层的编译代码。该目录包含了每种平台的子目录,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips。大多数情况下我们可以只用一种armeabi-v7a,后面会讲到原因;
    • resources.arsc:包含已编译的资源。该文件包含res/values/ 文件夹所有配置中的XML内容。打包工具提取此XML内容,将其编译为二进制格式,并将内容归档。此内容包括语言字符串和样式,以及直接包含在resources.arsc文件中的内容路径 ,例如布局文件和图像;
    • META-INF/:包含CERT.SF和 CERT.RSA签名文件以及MANIFEST.MF 清单文件;
    • AndroidManifest.xml:包含核心Android清单文件。该文件列出应用程序的名称,版本,访问权限和引用的库文件。该文件使用Android的二进制XML格式。
  • 实际开发中
    • image
      image

2.如何压缩优化apk

2.1 资源方面

  • 1.删除无用资源
    • 通过lint或resource shinking等删除无用资源。需要注意,别删错了!
  • 2.压缩图片
    • 1)无透明度的png转成jpg
    • 2)通过tinypng, tinyjpg等进行有损压缩,或通过ImageOptim进行无损压缩
    • 3)在不影响质量的提前下将大图转换成webp
  • 3.压缩动画
    • 压缩loading等gif动画,及其它较大的资源,如mp3
  • 4.动态加载
    • 对动态表情等特定业务场景才使用的动画等资源做动态加载,app启动后在线下载,不随apk发包。
  • 5.使用微信资源压缩方案
    • 方案见 https://github.com/shwenzhang/AndResGuard
  • 6.glide配置
    buildTypes {
        release {
            minifyEnabled true //是否开启混淆
            shrinkResources true //压缩
            zipAlignEnabled true ////去掉无用的resourse文件
        }
    }

2.2 Android原生对于WebP的支持

  • 我们知道Webp的压缩比例要比 png,jpg/jpeg的压缩比高,使用webp能减少一些包体积.
    • Android 4.0开始(sdk >= 14 ),原生的ImageView开始支持Webp,但是未支持透明通道
    • Android 4.2开始 (sdk >= 18)开始前面支持Webp
  • 也就是说你项目的 minSdk是4.2以上>=18那么恭喜你,你可以把所有图片转成webp格式,方法直接图片右键就可以转换.
  • 如果只是在4.0与4.2之间的那么,你就只能转一些不带透明通道的图片,如果其他你还想要Webp接入一个库,那增大包体积,和原生ImageView不支持,带来的成本挺大.

2.2 代码方面

  • 1.开启proguard
    • proguard不仅能够混淆,而且能够优化代码,可以大大减小dex文件的大小。
    • 但需要对被反射引用的类需要做好keep
  • 2.动态加载
    • 对ocr(身份证识别)等较大的库做动态加载,app启动后在线下载,不随apk发包。
  • 3.插件化
    • 将相对独立的业务做成插件,app启动后在线下载,不随apk发包。
  • 4.删除非必要的so库
    • 很多app为了支持x86,apk至少包含arm和x86 2个ABI,甚至包括arm其实x86构架的手机也支持arm,可以删除x86 so,只保留arm。
    • 有人认为x86手机以兼容模式运行arm so会影响效率,其实效率上的影响对用户并没有直接的感知。
    • 删除x86 so可以大大减少apk size,特别是app集成了很多第三方so库的情况下,如fresco,rn等。
    • 关于so的介绍详见Android 动态链接库加载原理及 HotFix 方案介绍
  • 5.Facebook字节码优化方案redex
    • 方案见 https://github.com/facebook/redex

3.其他操作

3.1 lint检查

  • 如下所示
    • https://developer.android.google.cn/studio/write/lint
    • https://www.jianshu.com/p/a0f28fbef73f
    • https://blog.csdn.net/u011240877/article/details/54141714

3.2 如何检测哪些无效代码

  • 使用Android Studio的Lint,步骤:点击菜单栏 Analyze -> Run Inspection by Name -> unused declaration -> Moudule ‘app’ -> OK
    • image
      image
  • 其他说明
    • Android > Lint > Correctness (可能影响程序正确性)
    • Android > Lint > Performance (可能影响程序性能)
    • Android > Lint > Security (可能影响程序安全性)

4.对比前后

  • 没有瘦身之前

参考博客

  • https://www.jianshu.com/p/78ad578251ef
  • https://www.jianshu.com/p/24eb823edebc

其他介绍

  • 包体积优化 · 工具论 · 初识包体积优化
    • https://juejin.cn/post/7176622003888226362
  • Android性能优化之APK瘦身详解(瘦身73%)
    • https://juejin.cn/post/7119445311868633096
贡献者: yangchong211
上一篇
18.App稳定性专项实践
下一篇
20.常见代码优化实践