来看看淘宝APP的unzip之后的文件目录
一般来讲APK结构中比较大的部分一般是classes.dex、lib、res、assets
这些文件或者目录。所以接下来将会针对这四种情况进行讲解。
另外,我们通过APK Analyser 可以分析 APK
02 减小 classes.dex
classes.dex 包含了所有 Java 代码。当你编译你的应用时,gradle 会将你的所有模块里的 .class 文件转换成 .dex 文件并将这些文件合成一个 classes.dex 文件。
单个的 classes.dex 文件可以容纳大约 64K 方法。如果你达到了这个限制,你必须要在你的工程中启用 multidexing。这将会创建另一个 classes1.dex 文件去存储剩下的方法。所以 classes.dex 文件数目由你的方法数而定。
减少第三库的使用
随着业务的频繁变更以及复杂度的增加,我们往往会使用第三方Libaray,有时候我们可能仅仅用到了很少一部分的功能,这个时候就需要慎重考虑完全引用。从我的开发经验上来讲,宁愿参照自己去实现,也不愿意多引入一个第三方库。
避免枚举
一个枚举可以为您的应用程序的classes.dex
文件添加大约1.0到1.4 KB的大小 。这些添加可以快速累积到复杂系统或共享库。如果可能,请考虑使用@IntDef
注释,这种类型转换保留了枚举的所有类型安全优势。
使用ProGuard
下面这段来自 build.gradle 文件的代码用于为发布构建启用代码压缩:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt’),
‘proguard-rules.pro’
}
}
…
}
除了 minifyEnabled 属性外,还有用于定义 ProGuard 规则的 proguardFiles 属性:
getDefaultProguardFile(‘proguard-android.txt’) 方法可从 Android SDK tools/proguard/ 文件夹获取默认的 ProGuard 设置。
提示:要想做进一步的代码压缩,请尝试使用位于同一位置的 proguard-android-optimize.txt 文件。它包括相同的 ProGuard 规则,但还包括其他在字节码一级(方法内和方法间)执行分析的优化,以进一步减小 APK 大小和帮助提高其运行速度。
proguard-rules.pro 文件用于添加自定义 ProGuard 规则。默认情况下,该文件位于模块根目录(build.gradle 文件旁)。
03 优化assets和res中的资源文件
题外话
res/raw和assets的相同点:
- 两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
res/raw
中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.raw.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。res/raw
不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹。
针对不同的情况,对于资源文件有不同的优化策略。一般来讲,对于res/drawable-hdpi中的png资源可以进行压缩。
图片资源优化策略
格式压缩
使用TinyPng或者Guetzli进行压缩。
使用WebP文件格式
定位Android 3.2(API级别13)或更高级别时 ,您也可以使用WebP文件格式来制作图像,而不是使用PNG或JPEG文件。WebP格式提供有损压缩(如JPEG)以及透明度(如PNG),但可以提供比JPEG或PNG更好的压缩。
Android 4.0 (API level 14) 支持有损压缩的WebP格式,Android 4.3 (API level 18) 开始支持无损透明WebP图像。
看下图:
压缩效率极高,仅为PNG格式的12%。惊喜不惊喜。。。
使用矢量图形
您可以使用矢量图形来创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以大大减少您的APK足迹。矢量图像在Android中表示为VectorDrawable对象。通过一个VectorDrawable对象,一个100字节的文件可以生成一个与屏幕尺寸一致的清晰图像。
但是,系统渲染每个 VectorDrawable对象需要很长时间,而较大的图像需要更长的时间才能显示在屏幕上。因此,只有在显示小图像时才考虑使用这些矢量图形。
其它策略
有时候我们可能对一张图片进行重复利用,比如一张图片仅仅是整体颜色的变换可以使用setColorFilter
或者tint
。尽量减少使用帧动画,那可是一堆图片呀。
压缩资源
要启用资源压缩,请在 build.gradle 文件中将 shrinkResources 属性设置为 true。
android {
…
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt’),
‘proguard-rules.pro’
}
}
}
资源压缩器目前不会移除 values/ 文件夹中定义的资源(例如字符串、尺寸、样式和颜色)。这是因为 Android 资源打包工具 (AAPT) 不允许 Gradle 插件为资源指定预定义版本。
同时,我们也可以指定哪些资源可以保留下来。
例如,将下边的代码保存在 res/raw/keep.xml。构建不会将该文件打包到 APK 之中。
<?xml version="1.0" encoding="utf-8"?>resources
有以下属性:
tools:keep 指出哪些资源会保留
tools:discard 指定哪些资源需要剔除
tools:shrinkMode 资源压缩模式,有两种取值strict和safe,默认为safe
safe
和strict
的优化策略:
safe可以简单理解为安全模式,它会尽最大努力检查代码中可能会使用到的资源进行保留,避免运行时错误。
如果你的代码调用 Resources.getIdentifier()),这就表示你的代码将根据动态生成的字符串查询资源名称。当你执行这一调用时,默认情况下资源压缩器会采取防御性行为,将所有具有匹配名称格式的资源标记为可能已使用,无法移除。
String name = String.format(“img_%1d”, angle + 1);
res = getResources().getIdentifier(name, “drawable”, getPackageName());
img_ 前缀的资源标记为已使用。
在strict模式下,img_前缀的资源会做未使用的处理,因此你需要使用tools:keep
手动进行已使用标识。
移除未使用的备用资源
我们知道google给我们的apk提供了国际化支持,如适应不同的屏幕分辨率的drawable资源,还有适应不同语言的字符串资源等等,但是在很多情况下我们只需要一些指定分辨率和语言的资源就可以了,这个时候我们可以使用resConfigs方法来配置。
defaultConfig {
// 对于国际化支持只打包中文资源,
resConfigs “zh-rCN”
}
04 lib中资源优化
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
资深开发者,这些资料都将为你打开新的学习之门**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!