这是 Android 官方文档给出的一些削减包体积的主张,最近正好在看这方面内容,顺手记载、分享一下。本文主要是针对 Android 的资源(Resource) 相关优化主张。
1 移除无用资源
运用 lint 静态代码剖析东西查找出未运用的 res
资源。
注意 assert
和 lib
下的未运用资源无法检测出来,其间 assert/ 资源引用采用的是反射办法。
除了检测东西外,Gradle 还支撑在打包编译的时分主动移除无用资源,运用 shrinkResources
:
android {
// Other settings
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
这儿 minifyEnabled
需求一同翻开,即代码紧缩。这样编译的时分会先用 R8
进行无用代码移除,然后 gradle 插件进行无用资源的移除。详细运用参考:Shrink, obfuscate, and optimize your app
除此之外,还能够运用 resConfig
装备针对指定的 flavor
来打包指定的资源。比方外发包的图片和第一方的包的资源不一样,装备在不同的文件夹下,打包的时分就能够只打包指定的文件夹资源,这样也能削减必定的体积。
2 削减依靠库巨细
开发的时分,在挑选第三方东西库时,需求关注一下该库的巨细。比方 Android 图片加载库 Glide、Picasso、Fresco 的挑选,将依靠库的体积巨细作为选用的衡量标准之一。
另外,假如只是运用某个东西库的其间一个(小)功能,是否能够考虑将其下载下来自行修正,适当移除不需求的功能代码,然后削减依靠库的体积。
3 原生动画图片支撑
运用 ImageDecoder
原生 API 支撑带动画的 GIF 和 WebP 的图片文件格局,然后删除第三方库削减包体积。
要求 Android 11 以上才支撑
4 支撑特定分辨率
从 Android 4.4 开端,支撑 ldpi
, mdpi
, tvdpi
, hdpi,
xhdpi
, xxhdpi
和 xxxhdpi
这么多的分辨率(屏幕密度,density),但是没有必要给每个分辨率都制作对应的图片资源。
也许你的用户只有 0.1% 的人需求 ldpi
…
这个时分,其实我们只需求一种分辨率的文件夹,比方 drawable-nodpi/
,关于其他的,体系会主动适配(扩大缩小)
官方引荐至少有一种分辨率
xxhdpi
5 运用 drawable 或代码渲染图片
有些单色布景图片其实不需求静态的图片文件,运用 Drawable
对象(xml 里的 )能够在运转的时分制作出来,然后节省出静态图片文件的巨细。
对应的,运用代码来生成某些简略的作用图(render from code),比方页面布景设置为纯色。
比较运用图片文件,能够减小必定的包体积巨细。
6 复用资源
某些情况下,两张图片可能除了视点或许色彩不一样,其他都是一样的,这个时分,我们就不引荐运用2张图片,能够经过代码来上色或许旋转。
图片的纯上色(改动色彩),大于 Android 5.0(API 21) 的体系能够运用 android:tint
和 tintMode
,小于 Android 5.0 的版本运用 ColorFilter
来完成。
改动图片的旋转视点,比方上箭头改为下箭头这种,运用下面这样即可:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_thumb_up"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="180" />
7 紧缩图片资源文件
官方内置的东西 aapt,在编译的时分,会主动对 res/drawable/
(其他目录无效,比方 asset/
)里面的图片进行无损紧缩(lossless compression),假如不需求,能够手动封闭:
buildTypes.all { isCrunchPngs = false }
需求注意的是,isCrunchPngs 在 release 默许翻开(这会添加编译时间),debug 下默许封闭。
选用第三方东西进行不同格局图片紧缩:
- PNG 运用 Pngcrush (引荐)、pngquant、zopfli
- JPEG 运用 packJPG、Guetzli
8 运用 WebP 文件格局
Android 3.2(API 13) 之后开端支撑 WebP 图片格局。
WebP 比较 JPEG 和 PNG 有更好的紧缩功率(即紧缩的体积更多,损失越小),能够直接在 Android Studio 里面将 BMP, JPG, PNG 或许静态 GIF 图片转换为 WebP 格局。
JPEG 为有损紧缩(lossy compression) PNG 为无损数据紧缩,主要体现在通明度上的改变。(lossless data compression,a raster-graphics file format)
9 运用矢量图形(vector graphics)
矢量图形是一种与分辨率无关的图片,100字节巨细的文件能够描绘出充满整个屏幕的高清图片。
矢量图形在代码里用 VectorDrawable
表示。
但是有必定的功能问题。矢量图形本质上就是一系列 xml 数据,Android 体系依据矢量图形的“描绘”调用 cpu\gpu 去制作出来一张图:比方x坐标以上涂满红色,y坐标以下涂满绿色,哪里哪里填上灰色…
合适用于小面积的图标(icon)制作,不合适大面积的图画制作,有必定的功能消耗。
比如:
<!-- res/drawable/battery_charging.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group
android:name="rotationGroup"
android:pivotX="10.0"
android:pivotY="10.0"
android:rotation="15.0" >
<path
android:name="vect"
android:fillColor="#FF000000"
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z"
android:fillAlpha=".3"/>
<path
android:name="draw"
android:fillColor="#FF000000"
android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z"/>
</group>
</vector>
渲染生成:
还有动画作用也能够运用 vector graphics 来完成,参考 AnimatedVectorDrawableCompat
(比照运用逐帧动画,需求放入很多的单帧图片组合一个动画,极大添加了apk包巨细!)
参考
Reduce your app size