APK作为Android系统安装包的文件格式,一直备受广大用户的关注,APK越是臃肿肥大,在下载安装过程中,它们耗费的流量会越多,安装等待时间也会越长;对于产品本身,意味着下载转化率会越低(因为竞品中,用户有更多机会选择那个体验最好,功能最多,性能最好,包最小的);对于研发来说,是一种优化改进技术的机会。今天老司机将带领大家一起探讨下APK脂肪含量最高的图片资源瘦身套路。
套路一:查找并清除未使用图片资源
通常使用AndroidStudio中自带的Lint工具来帮助我们查找未使用的图片资源,在AndroidStudio的菜单中选择Analyze->Inspecting Code即可进入Lint工具分析。
分析过后,我们在结果列表中找到Unused resource这一栏打开,里面显示的都是未被使用的资源列表,用户可以参照来手动删除资源。
套路二:使用tinypng优化Android的资源图片
最简单的使用点击上图中虚线框,上传需要压缩的图片
需要注意的是:
- tinypng支持png和jpg图片的压缩,并且也支持9图的压缩。
- tinypng的缺点是在压缩某些带有过渡效果(带alpha值)的图片时,图片会失真。
- tinypng提供了开放接口供开发者开发属于自己的压缩工具,不过这是付费服务,对于普通用户来说,tinypng为每个用户提供的每月图片免费压缩数量已经足够了。
套路三:将Android的资源图片转化成Webp
Webp是由google开发支持的新型图片格式,同时提供有损和无损压缩。WebP最初在2010年发布,目标是在最小的压缩损失下,提供尤其是在网络上应用的开放图片格式,竞争JPEG。Webp可达到与jpg不相上下的图片质量,但是有着更小的文件,可以减少图片档的传送时间。
官方介绍:https://developers.google.com/speed/webp/docs/precompiled
具体使用可以参考该教程:https://blog.netsh.org/posts/convert-webp-file_1353.netsh.html
套路四:不是每张图片都需要适配多套分辨率
通常开发中我们会据不同尺寸的屏幕让美工给我们切出多套图片,比如hdpi、mdpi、xhdpi、xxhdpi、xxxhdpi等。但是实际上有些图片可能不需要放置多套,比如ldpi分辨率的种手机目前很少了。
此外,我们所引入的第三方包中可能也引用了资源图片,但是其中的某些我们可能是不想要的,比如ldpi和xxxhdpi,那么是否可以设置什么东西来让打包的时候剔除他们呢?是可以的,可以配置下build.gradle
defaultConfig {
resConfigs "en", "de", "fr", "it"
resConfigs "hdpi", "xhdpi", "xxhdpi"
}
defaultConfig提供了resConfig这个flavor来指定打包出只打包某些资源,比如字串、图片等等。
套路五:覆盖第三方库里的大图
很多时候我们引入了大量的第三方库,这些第三方库里又引用了一些大图但是实际上并不会被我们用到,删除又怕出错,这时候我们就可以考虑用1x1的透明图片覆盖,已达到减少图片资源空间占用的问题。
套路六:使用9.png图
9.png格式的图片在android 环境下具有自适应调节大小的能力。
(1)允许开发人员定义可扩展区域,当需要延伸图片以填充比图片本身更大区域时,可扩展区的内容被延展。
(2)允许开发人员定义内容显示区,用于显示文字或其他内容
对于9.png的图片,在绘制过程中,可拉伸区域尽量切小,另外可以通过使用9.png拉伸达到大图效果的时候尽量不要使用整张大图。
套路七:用代码代替图片
使用shape制作背景图
- 很多背景图比如按钮的背景、纯色背景都是可以用shape来制作的,这样仅用xml代码就能代替png资源。比如这么要给按钮背景图(纯色背景、带边框、圆角)可以用shape而不是png图片来制作:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<stroke android:width="0.5dp" android:color="@android:color/white"/>
<gradient android:startColor="#ffffff" android:endColor="#ffffff" android:angle="0.0" />
<corners android:topLeftRadius="4dp" android:topRightRadius="0dp" android:bottomLeftRadius="4dp" android:bottomRightRadius="0dp" />
</shape>
</item>
</selector>
用RotateDrawable代替仅仅是方向不同的“内容相同”的图片
这里两个图片是两个按钮箭头,但是仅仅方向不同而已,其实可以只用其中一个图片即可,而另一个用RotateDrawable来让其“调转”180度:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_arrow_left"
android:fromDegrees="180"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="180" />
用layer-list来制作多层图片从而达到复用
- 有些需求中需要一种图片,但是明显这个图片是其他几个图片简单叠加而已,那么可以使用layer-list来达到目的:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<!-- 最底层的图片,以x,y轴坐标为中心进行旋转-->
<rotate android:pivotX="0" android:pivotY="0"
android:fromDegrees="-10" android:toDegrees="-10">
<bitmap android:src="@mipmap/ic_launcher"/>
</rotate>
</item>
<!-- 第二层的图片,以x,y轴坐标为中心进行旋转-->
<item>
<rotate android:pivotX="0" android:pivotY="0"
android:fromDegrees="15" android:toDegrees="15">
<bitmap android:src="@mipmap/ic_launcher"/>
</rotate>
</item>
<!-- 最上层的图片,以x,y轴坐标为中心进行旋转-->
<item>
<rotate android:pivotX="0" android:pivotY="0"
android:fromDegrees="35" android:toDegrees="55">
<bitmap android:src="@mipmap/ic_launcher"/>
</rotate>
</item>
</layer-list>
套路八:用一张图片实现按钮按下和普通效果的样式
方法:使用selector做遮罩,原图做background
我们做按钮的时候经常需要用两个图片来实现按钮点击和普通状态的样式,这就需要提供两种图片,而且每个分辨率下还有多套图片,大大增加了apk的大小。
我们希望让这两张图片合二为一,而且还能实现两种或者多种状态,怎么做呢?我们首先建立一个圆形的selector,正常情况下是完全透明的,按下后透明度变小。
castiel_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="#21000000" />
</shape>
</item>
<item>
<shape android:shape="oval">
<solid android:color="#00000000" />
</shape>
</item>
</selector>
然后我们需要把selector文件当作遮罩,用上面的安卓icon作为bg,放到一个ImageButton中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageButton
android:id="@+id/btn_test"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/castile_selector"
android:background="@mipmap/ic_launcher" />
</LinearLayout>
总结
通过以上八大套路,相信已上车的小伙伴都能很好地掌握APK图片资源瘦身方法,选择适合自己项目的套路,相信你的APK会成功瘦掉图片资源这块脂肪。