写点什么

Android 可能你想要的 APK 瘦身笔记,2021 最新安卓大厂面试题来袭

  • 2021 年 11 月 08 日
  • 本文字数:2404 字

    阅读完需:约 8 分钟

  • assets 目录:用于存放需要打包到 APK 中的静态文件和 res 的不同点在于,assets 目录支持任意深度的子目录,用户可以根据自己的需求任意部署文件夹架构,而且 res 目录下的文件会在.R 文件中生成对应的资源 ID,assets 不会自动生成对应的 ID(在不动业务逻辑,或者代码逻辑的情况下,针对此项很难优化)

  • lib 目录:存放应用程序依赖的 native 库文件, .so 的形式存在

  • res 目录:res 是 resource 的缩写,这个目录存放资源文件

  • resources.arsc 文件:编译后的二进制资源文件

  • META-INF 目录:保存应用签名信息,此处可验证 APK 的完整性,签名等

  • AndroidManifest.xml:应件文件配置信息

  • classes.dex:


下面我们来说一下优化的具体实施有哪些.


classes.dex 中常量 R 文件及内敛类的删除 * .R$ *


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


========================================


我们知道,Android 的 Res 资源会生成 R 文件的引用,如下


public final class R {private R() {}public static final class id {public static final int action_container = 2131165209;public static final int action_divider = 2131165211;public static final int action_image = 2131165212;public static final int action_text = 2131165218;public static final int actions = 2131165219;public static final int async = 2131165226;public static final int blocking = 2131165232;public static final int chronometer = 2131165246;public static final int forever = 2131165290;public static final int icon = 2131165299;public static final int icon_group = 2131165300;public static final int info = 2131165305;public static final int italic = 2131165309;public static final int normal = 2131165373;public static final int notification_background = 2131165374;public static final int notification_main_column = 2131165375;public static final int notification_main_column_container = 2131165376;public static final int right_icon = 2131165405;public static final int right_side = 2131165406;public static final int tag_transition_group = 2131165453;public static final int text = 2131165456;public static final int text2 = 2131165457;public static final int time = 2131165461;public static final int title = 2131165462;


private id() {}}


public static final class drawable {.......}


public static final class dimen {...}....}


这都是些常量,那我们有没有办法删除这个文件呢,引用的地方直接使用常量的值?事实是可以的. 根据 APK 打包的编译过程,在编译过程中使用 Android 的 Transform 替换所有的类里面的常量. BuildConfig, R



layout, R$string,AppConstans, etc


目前滴滴开源了一个 booster 可以直接使用,不用在自己造轮子


booster-transform-shrink

效果

组件化后或者依赖第三方 R 文件越来越多,常量比较多时,效果比较显著 据抖音的一哥们说,他们项目针对此项目优化后,包体积减少 2M 左右.


在我们项目上使用,不是很明显,优化体积 1M 左右.

注意事项

因为是删除常量,所有使用反射的地方也需要 keep 住,如果使用滴滴的 booster,可以参考 issues

Res 资源

Android Lint 去除无用资源

当我们项目迭代不断迭代,总有些资源逐渐不在使用,成为了冗余,当很多时候又懒得删,或者怕删了出问题. Android Studio 自带 lint 工具可以帮助我们清楚这些无用资源.(这里的清楚和 shrinkResources 去除无用是不一样的)

使用方法入口



除了 Android Studio Analyze 下的 Android Lint(Inspect Code) 用来去除无用资源,包体积优化,对于我们的代码一些自动优化也有很明显的效果. (性能,安全,bug 预防等)


  • Android > Lint > Correctness (可能影响程序正确性)

  • Android > Lint > Performance (可能影响程序性能)

  • Android > Lint > Security (可能影响程序安全性)


Lint 详细使用说明:google.cn/studio/lint


还有 Code Cleanup 也很强大,可以减少一些人为代码 review 不规范的地方.

图片

针对图片的优化,主要有一下几点

.9 图片

使用.9 图片来代替一些可重复区域的大图,可以借助 Android Studio 或者 sdk 下的.9 工具来制作.9 图片

xh-dpi

国内应用除了应用的 icon,大部分应用只设置了一套资源 xh-dpi,所以推荐使用一套图片资源

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 不支持,带来的成本挺大.

图片压缩

图片压缩也是只要的一个环节. 图片压缩的工具很多,png,webp 都可以很容易的压缩,对于应用质量体积有较高要求的,建议使用有损压缩,对图片视觉上的效果影响不大.


这里还是推荐 使用 booster 的压缩工具,可以 png 和 webp 压缩,针对 webp 的压缩针对了不同 minSdk 版本,进行了不同压缩策略. booster-task-compression

resources.ars 优化

我们知道 res 里面的资源文件名引用一般是这样的,例如将 res/drawable/welcome.png 那么打包的时候,是不是可以改成这样 r/s/a.png. 事实是可以的,类似 java 的混淆规则去混淆资源,这样,所占用的字节数就会降低. 但是存在一个问题就是,这些资源资源 ID 已经被编译成 32 位 int 值,放入了 resources.arsc.那么混淆的同时就要修改 resources.arsc. 张绍文 tinker 作者,前微信的技术大年,开源了 AndResGuard,可以解决这样的方案,并且优化还可以.具体使用详解 AndResGuard

build.gradle 配置

评论

发布
暂无评论
Android 可能你想要的APK瘦身笔记,2021最新安卓大厂面试题来袭