缩减资源数量和大小
1、图片优化
1.1使用矢量图
矢量图可以创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与屏幕大小相同的清晰图片。不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上。因此,建议仅在显示小图片时使用这些矢量图
1.2 使用.9图代替部分图片
1.3使用可绘制对象
某些图片不需要静态图片资源;框架可以在运行时动态绘制图片。
Drawable
对象(XML 中为<shape>
)会占用 APK 中的少量空间。此外,XMLDrawable
对象会生成符合 Material Design 准则的单色图片
1.4仅支持特定密度
如果您不添加用于特定屏幕密度的资源,Android 会自动缩放最初为其他屏幕密度设计的现有资源。
如果您的应用仅需要缩放的图片,则可以通过在
drawable-nodpi/
中使用图片的单个变体来节省更多空间。我们建议每个应用至少包含一个xxhdpi
图片变体。有关屏幕密度的详情,请参见屏幕尺寸和密度。
1.5重复使用资源
Android 提供了一些实用程序来更改资源的颜色。在 Android 5.0(API 级别 21)及更高版本上,使用
android:tint
和tintMode
属性,对于较低版本的平台,则使用ColorFilter
类
1.6使用 WebP 文件格式
1.7压缩 PNG 和 JPEG 文件
2、移除未使用资源
2.1启用资源缩减
如果在应用的 build.gradle 文件中启用了资源缩减: shrinkResources ,则 Gradle 在打包APK时可以自动忽略未使用资源。 资源缩减只有在与代码缩减: minifyEnabled 配合使用时才能发挥作用。在代码缩减器移除所有不使用的代码后,资源缩减器便可确定应用仍要使用的资源
android {
// Other settings
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
2.2使用Lint分析器(物理删除)
lint 工具是 Android Studio 中附带的静态代码分析器,可检测到 res/ 文件夹中未被代码引用的资源。从菜单栏中依次选择 Analyze > Run Inspection By Name (unused resources)
lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,只会提醒您它们的存在
2.3自定义要保留的资源
如果有想要特别声明需要保留或舍弃的特定资源,在项目中创建一个包含 <resources> 标记的 XML 文件,并在 tools:keep 属性中指定每个要保留的资源,在 tools:discard 属性中指定每个要舍弃的资源。这两个属性都接受以逗号分隔的资源名称列表。还可以将星号字符用作通配符
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
tools:discard="@layout/unused2" />
将该文件保存在项目资源中,例如,保存在 res/raw/keep.xml 中。构建系统不会将此文件打包到 APK 中
2.4移除未使用的备用资源
Gradle 资源缩减器只会移除未由应用代码引用的资源,这意味着,它不会移除用于不同设备配置的备用资源。可以使用 Android Gradle 插件的 resConfigs 属性移除应用不需要的备用资源文件
android {
defaultConfig {
...
resConfigs "zh-rCN"
}
}
配置resConfigs 只打包默认与简体中文资源
2.5动态库打包配置
so文件是由ndk编译出来的动态库,是 c/c++ 写的,所以不是跨平台的。ABI 是应用程序二进制接口简称(Application Binary Interface),定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统中,每一个CPU架构对应一个ABI,目前支持的有:armeabi-v7a,arm64- v8a,x86,x86_64。目前市面上手机设备基本上都是arm架构, armeabi-v7a 几乎能兼容所有设备。因此可以配置:
android{
defaultConfig{
ndk{
abiFilters "armeabi-v7a"
}
}
}
对于arm64架构的设备,如果使用armeabi-v7a也能够兼容,但是不如使用arm64的so性能。因此现在部分应用市场会根据设备提供不同架构的Apk安装。此时我们需要打包出针对arm64的apk与armv7a的apk,可以使用productFlavor :
flavorDimensions "default"
productFlavors{
arm32{
dimension "default"
ndk{
abiFilters "armeabi-v7a"
}
}
arm64{
dimension "default"
ndk{
abiFilters "arm64-v8a"
}
}
}
也可以使用:
splits {
abi {
enable true
reset()
include 'arm64-v8a','armeabi-v7a'
// exclude 'armeabi'
universalApk true //是否打包一个包含所有so的apk
}
}
2.6开启资源混淆
3避免使用枚举
单个枚举会使应用的
classes.dex
文件增加大约 1.0 到 1.4KB 的大小。这些增加的大小会快速累积,产生复杂的系统或共享库。如果可能,请考虑使用@IntDef
注释和代码缩减移除枚举并将它们转换为整数。此类型转换可保留枚举的各种安全优势