前言
Apk瘦身是一个高级开发需要掌握的高级技能。
APK结构
包含以下目录
- 1.assets/:包含了应用的而资源,这些资源可以通过AssetManager对象获得。
- 2.lib/: 包含针对处理器层面的被编译的代码。这个目录针对每个平台类型都有一个子目录,比如armebi,armebi-v7a,arm64-v8a,x86,x86_64和mips
- 3.res/:包含了没被编译到resources.arsc的资源
- 4.META-INF/:包含了CERT.SF 和CERT.RSA签名文件,也包含了MANIFEST.MF文件。(校验这个APK是否被人改动过) 包含以下文件
- 4.classes.dex: 包含了能被Dalvik/Art虚拟机理解的dex文件格式的类
- resources.arsc :包含了被编译的资源,该文件包含了res/values目录的所有配置的xml内容。打包工具讲xml内容编译成二进制形式并压缩,这些内容包含了语言字符串和style,还包含了哪些内容虽然不直接存储在resources.arsc文件中,但是给定了该内容的路径,比如布局文件和图片,所以又叫资源映射表。
- AndroidManifest.xml:包含了主要的Android配置文件。这个文件列出了应用名称、版本、访问权限、引用的库文件。该文件使用二进制存储(还能看到应用的minSdkVersion targetSdkVersion等信息)。
启用资源缩减 (不打包)
如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources ,则 Gradle 在打包APK时可以自动忽略 未使用资源。 资源缩减只有在与代码缩减: minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不 使用的代码后,资源缩减器便可确定应用仍要使用的资源 。
使用lint分析器
该方式存在缺陷 会删掉通过代码调用getIndetify的资源
动态库打包配置
so文件是由ndk编译出来的动态库,是 c/c++ 写的,所以不是跨平台的。ABI 是应用程序二进制接口简称 (Application Binary Interface),定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的 指令集,内存对齐到可用的系统函数库。在Android 系统中,每一个CPU架构对应一个ABI,目前支持的有: armeabi-v7a,arm64- v8a,x86,x86_64。目前市面上手机设备基本上都是arm架构, armeabi-v7a 几乎能兼容 所有设备。因此可以配置:
对于第三方服务,如百度地图、Bugly等会提供全平台的cpu架构。进行了上面的配置之后,表示只会把armeabiv7a打包进入Apk。从而减少APK大小。 对于arm64架构的设备,如果使用armeabi-v7a也能够兼容,但是不如使用arm64的so性能。因此现在部分应用市 场会根据设备提供不同架构的Apk安装。此时我们需要打包出针对arm64的apk与armv7a的apk,可以使用 productFlavor 。
1.减少资源图片大小(采用SVG)
Apk中图片应该算是占用空间最多的资源。我们可以使用webp减少png、jpg图片占用空间的大小。对于小图标也 可以使用矢量图。 矢量图可以创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图 片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与 屏幕大小相同的清晰图片。 不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕 上。因此,建议仅在显示小图片时使用这些矢量图。
1.SVG导入
SVG(可缩放的矢量图),svg不会像位图一样因为缩放而让图片质量下降。优点在于可以减少apk的尺寸,常用于小图标。
svg是由xml定义的,标准的svg根节点为。Android中只支持,我们可以通过vector将svg的根节点转换成。
在androidstudio中打开工程,在res目录中点击右键
2.SVG批量导入
上述只是针对少量SVG图片的手动导入,如果有多个,可以考虑第三方工具svg2vector 进行批量转换。
执行转换命令:
java -jar svg2vector-cli-1.0.0.jar -d . -o a -h 20 -w 20
-d 指定svg文件所在目录
-o 输出android vector 图像目录
-h 设置转换后svg的高
-w 设置转换后svg的宽
3.不支持SVG
如果SVG文件包含不受支持的功能,将在vector Asset Studio的底部显示一个错误提示。如
- 1.滤镜效果:不支持投影、模糊和颜色矩阵等效果。
- 2.文本:建议使用其他功夫剧将文本转化为形状。
矢量图向后兼容-生成PNG
Android 5.0(API21) 之前的版本不支持矢量图,使用vector Asset Studio有2种方式适配。
方式一:生成png格式的图片
vector Asset Studio 可在构建时 针对每种屏幕密度将矢量图转换成不同大小的位图,在build.gradle中配置如下:
SVG适用于Gradle插件1.5及以上版本:
defaultConfig {
//5.0版本以下,将svg图片生成指定维度的png图片
generatedDensities = ['xhdpi','xxhdpi']
}
方式二:支持库(矢量图向后兼容)
在 build.gradle 中配置如下,适用于 Gradle 插件2.0及以上版本:
android{
// Gradle Plugin 2.0+
defaultConfig{
// 利用支持库中的 VectorDrawableCompat 类,可实现 2.1 版本及更高版本中支持 VectorDrawable
vectorDrawables.useSupportLibrary = true
}
}
dependencies {
// 支持库版本需要是 23.2 或更高版本
compile 'com.android.support:appcompat-v7:23.2.0'
}

使用矢量图 必须使用 app:srcCompat 属性,而不是 android:src,如下:
矢量图在android里面格式
矢量图实现图片选择器效果
减少国际化资源配置
因为默认下 即时我们没有适配配置各种语言的,但是系统还是会给我们进行了配置,所以我们还是需要手动去配置指定的资源配置
动态库打包配置
压缩代码
压缩资源
资源混淆(因为资源混淆后会将文件名改成a b c之类的字母 这样也能减少apk大小)
混淆步骤
public class Main {
public static String OUTDIR = "resguard-tools/build/andres";
public static String CONFIG = "resguard-tools/config";
public static void main(String[] args) throws Exception {
// 7z a -tzip xxx.apk src/* -mx=9 极限压缩
// 修改apk中某个文件极限压缩为不压缩,如res/raw/a.mp3、assets/a.mp3等文件 不能压缩 否则无法播放
// 7z a -tzip xxx.apk src/* -mx=0 不压缩
//强制压缩列表 使用7z压缩apk
List<String> forceCompress = readForceCompress(CONFIG + "/compressData.txt");
//待处理APK
File apkFile = new File("app/build/outputs/apk/debug/app-debug.apk");
System.out.println(apkFile.getAbsolutePath());
//混淆并压缩apk
Obfuscater obfuscater = new Obfuscater(forceCompress, apkFile);
obfuscater.obfuscate();
}
static List<String> readForceCompress(String config) throws Exception {
ArrayList<String> compressData = new ArrayList<>();
File compress = new File(config);
FileInputStream fis = new FileInputStream(compress);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line;
while ((line = reader.readLine()) != null) {
compressData.add(line);
}
reader.close();
return compressData;
}
}
混淆ARSC文件
其他!
- 使用精简版本的依赖:如protobuf-lite版本;对于分模块的库按需引入:如netty分模块引入;
- 主动移除无用代码(开启R8/Progurad自动移除)
- 避免使用枚举,使用 @IntDef 代替。
- 开启资源混淆:github.com/shwenzhang/…
- 支付宝删除Dex debugItem juejin.im/post/684490…
- 对于发布Google paly的应用选择使用:AAB developer.android.google.cn/guide/app-b…