版权声明:本文为博主原创文章,未经博主允许不得转载。
本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。
一、使用 SVG
Scalable Vector Graphics,可缩放矢量图。SVG 不会像位图一样因为缩放而让图片质量下降。优点在于节约空间与内存。常用于简单小图标。
1. svg 是由 xml 定义的,标准 svg 根节点为 <svg>
2.在 Android 中通过 Vector 实现对 svg 的支持,根节点为 <vector>。
4.获得一张 svg 需要先进行转换才能在 android 当中使用。
在之前的一篇博客 (十六、SVG) 中有专门对安卓中使用 SVG 进行了介绍。
附 安卓官网 链接。
二、Tint 着色器
Tint 能够实现图片变色,利用 Tint 显示不同颜色的图片,原本需要多张相同图片不同颜色的情况,这时候只需要一张图片就可以,能够减少 apk 的体积。
1.简单使用
布局:
<!--原始图片-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tint" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tint"
android:tint="@color/colorAccent" />
原始图片,白色透明背景。
效果图:
2.代码设置变色
//代码设置tint
Drawable drawable = getResources().getDrawable(R.drawable.tint);
DrawableCompat.setTint(drawable,getResources().getColor(R.color.colorAccent));
3.点击变色
布局:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="@drawable/tint_src_selector"
android:tint="@color/tint_color_selector" />
tint_src_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tint" android:state_pressed="true" />
<item android:drawable="@drawable/tint" />
</selector>
tint_color_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimary" android:state_pressed="true" />
<item android:color="@color/colorAccent" />
</selector>
效果:
**注:**图片的设置中,虽然触摸与非触摸状态的图片是同一个,但是必须设置,否则不能生效。
三、瘦身之旅
拿目前手头上的一个项目进行当前的瘦身之旅。
未优化的时候,apk 的包大小为 31353 KB。
1.使用 WebP
在 (十七)WebP 的测试与使用 中介绍了 WebP 的使用。
在这边,我们把图片转换为 WebP 格式的图片。
使用 WebP 后,apk 的大小减少了大概 4M。(这边 WebP 图片生成的参数是使用 Android Studio 默认的,如果质量设置更校,图片可以更小)。
2.资源打包配置
在 Android Studio 中打开 apk,查看 resources.arsc 文件下的 string。
可以发现 apk 打包了一些我们不需要的语言包,这是因为我们引入了 v7 包或者其他依赖包,在依赖包中有进行国际化,所以这些语言包也被打包进来。
在 app 下的 build.gradle 中进行配置。
android {
compileSdkVersion 28
defaultConfig {
......
// 只保留英文的语言包
resConfig 'en'
}
}
这个配置减少的大小不多,具体多少要看原本 apk 里面多余的语言包大小。
3.动态库打包配置
我们的 apk 中,难免需要用到第三方插件,这些插件很经常会有对应的动态库在里面。我们查看当前 apk 下的 lib 目录。
发现 lib 目录有 arm64-v8a 和 armeabi-v7a 这两个包,有些可能还有 x86 等。目前市面上大部分手机来说, armeabi-v7a 就足够了(微信也是只有这个包)。
在 app 下的 build.gradle 中进行配置。
android {
compileSdkVersion 28
defaultConfig {
......
ndk{
abiFilters "armeabi-v7a"
}
}
}
动态库占用的带下还是相对比较可观的,特别是当应用引入较多的第三方库,这些库又包含大量的 so 。
4.移除无用资源
1.一键移除
Android Studio 中可以一键移除无用资源。
如果出现使用动态 id 使用资源会出现问题。所以不推荐使用这个。
动态获取资源 id ,未直接使用 R.xx.xx ,则这个 id 代表的资源会被认为没有使用过(类似不能混淆反射类)。
动态获取资源 id:
2.使用 Lint 检查
在弹出框输入 unused resources。
这边选择在 app 下进行搜索。
在下方会搜索出一些没有使用到资源,最好再对照代码,一个个确认是否未使用,然后进行删除。
在项目的修改中,有时候删除了一些 Activity 或者布局,但是对应的资源忘记删除,在一次次修改中,会有越来越多的无用资源。特别是图片资源比较大。
5.开启 Proguard
开启 Proguard 会进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preveirfy)。
1. 压缩(Shrink):在压缩处理这一步中,用于检测和删除没有使用的类,字段,方法和属性。
2. 优化(Optimize):在优化处理这一步中,对字节码进行优化,并且移除无用指令。
3. 混淆(Obfuscate):在混淆处理这一步中,使用 a,b,c 等无意义的名称,对类,字段和方法进行重命名。
4. 预检(Preveirfy):在预检这一步中,主要是在 Java 平台上对处理后的代码进行预检。
压缩时候会删除没有用的类,方法和属性,如果使用了反射,这个类也会被删除。
开启 Proguard,压缩和优化这两步骤会溢出一些无用的代码。从而对 apk 进行瘦身。
app 下的 build.gradle 中进行配置,同时配置对应的混淆配置文件。
build.gradle:
android {
......
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
}
6.启动资源缩减
资源压缩只与代码压缩协同工作。经过前面第 2 步,正常情况下我们应用中的资源都是有用到的,但是在第 5 步中,我们移除了一些没有用的类,但是没有把对应的资源文件删除。所以,在这里对这些文件进行缩减。特别是第三方库,如:v7 包等。
app 下的 build.gradle 中进行配置。
build.gradle:
android {
......
buildTypes {
debug {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
}
同时,创建 res/raw/keep.xml 文件,开启严格引用检查(官网链接有详细说明)。
keep.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:shrinkMode="strict" />
7.其他压缩
资源混淆与 7Zip 压缩:
apk 中 resource.arsc 里面保存有各个文件资源名的字符串,资源混淆的时候会使这些字符串变短,从而使 resource.arsc 文件变小,达到 apk 的瘦身。
在资源混淆后,重新打包 apk 的时候,使用 7Zip 进行打包,可以压缩到更小的体积。
该方案较复杂,就不再这边详细讲解,资源混淆压缩的体积不多,但是 7Zip 压缩减小的体积还是提多的。
v1/v2 签名:
使用 v1 签名会在 META-INF/ 生成签名校验文件
使用 v2 签名会向 zip 文件按照格式插入字节数据
同时使用两种签名会增加两份数据(文件+数据),提供配置 v1/v2 签名开关
v2 签名相比 v1 签名对 apk 体积影响更小,所以尽量使用 v2 签名。但是 v2 签名有版本的限制,需 Android 7.0 之后。
全版本允许: 只使用 v1 方案
全版本允许: 同时使用 v1 和 v2 方案
>=7.0版本: 只使用 v2 方案