Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android性能优化—— Apk瘦身的实现

$
0
0

APK文件结构

  为了能够减小APK的大小,首先需要知道APK由哪些部分构成,然后针对每个部分做相应的优化工作,下图是一个APK解压后的文件结构:

文件或目录 作用
META-INF/ 也就是一个 manifest ,从 java jar 文件引入的描述包信息的目录
res/ 存放资源文件的目录
libs/ 如果存在的话,存放的是 ndk 编出来的 so 库
AndroidManifest.xml 程序全局配置文件
classes.dex 最终生成的 dalvik 字节码
resources.arsc 编译后的二进制资源文件

减少代码和资源冗余

APK中classes.dex、lib、资源文件是大头,APK瘦身主要就是优化这三类,关于这三种类型的文件比较成熟的优化方法有:

  • classes.dex:通过代码混淆,删掉不必要的jar包和代码实现该文件的优化;
  • lib:一个硬件设备对应一个架构(mips、arm或者x86),只保留与设备架构相关的库文件夹(主流的架构都是arm的,mips属于小众,默认也是支持arm的so的,但x86的不支持),这样可以大大降低lib文件夹的大小;
  • 资源文件:通过Lint工具扫描代码中没有使用到的静态资源。

上面介绍的三种类型文件的优化方案的确能够在一定程度上减小APK的大小,但在最近做项目的过程中经过研究发现还可以更进一步优化APK的大小,具体方案如下:

多分辨率适配:我之前写过一篇关于多分辨率适配的文章 Android多分辨率适配经验总结 ,一套图、一套布局,多套dimens.xml文件,在使用最小资源的情况下搞定多分辨率适配;

按需加载数据资源

预置数据:和游戏一样,程序和数据分离,进入模块时下载预置数据(下载的策略需要注重用户体验,在需要使用数据的地方下载)。

图片资源优化攻略

图片资源的优化原则是:在不降低图片效果、保证APK显示效果的前提下缩小图片文件的大小。

使用tinypng优化大部分图片资源

tinypng 是一个支持压缩png和jpg图片格式的网站,通过其独特的算法(通过一种叫“量化”的技术,把原本png文件的24位真彩色压缩为8位的索引演示,是一 种矢量压缩方法,把颜色值用数值123等代替。)可以实现在无损压缩的情况下图片文件大小缩小到原来的30%-50%。压缩率和压缩后的效果如下:

上面的图片对比举例不太好,不过可以看到压缩前后图片效果并没有变化,需要说明的是:tinypng支持png和jpg图片的压缩,并且也支持9图的压缩。

tinypng的缺点是在压缩某些带有过渡效果(带alpha值)的图片时,图片会失真,这种图片可以将png图片转换为下面介绍的webP格式,可以在保证图片质量的前提下大幅缩小图片的大小。

tinypng提供了开放接口供开发者开发属于自己的压缩工具,不过这是付费服务,对于普通用户来说,tinypng为每个用户提供的每月图片免费压缩数量已经足够了。

使用webP图片格式

WebP 是谷歌研发出来的一种图片数据格式,它是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。目前很多公司已经将webP技术运用到Android APP中,比如FaceBook、腾讯、淘宝。webP相比于png最明显的问题是加载稍慢,不过现在的智能设备硬件配置越来越高,这都不是事儿。

假如你打算在 App 中使用 WebP,除了 Android4.0 以上提供的原生支持外,其他版本以可以使用官方提供的解析库 webp-android-backport 编译成so使用。

通常UI提供的图片都是png或者jpg格式,我们可以通过 智图 或者isparta将其它格式的图片转换成webP格式,isparta可实现批量转换,墙裂推荐!

使用tintcolor实现按钮反选效果

通常按钮的正反旋图片我们都是通过提供一张按钮正常图片和一张按钮反选图片,然后通过 selector 实现,两张图片除了alpha值不一样外其它的内容都是重复的,在Android 5.0及以上的版本可以通过 tintcolor 实现只提供一张按钮的图片,在程序中实现按钮反选效果,前提是图片的内容一样,只是正反选按钮的颜色不一样。

下面是个例子:

btn_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_pressed" android:state_pressed="true" />
    <item android:drawable="@drawable/btn_bg" />
</selector>

其中btn_bg为png图片,而btn_begin_pressed则是使用此图进行tint着色后的xml文件.

btn_pressed.xml:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/btn_bg"
    android:tint="@color/colorAccent"
    android:tintMode="multiply">

</bitmap
...
 <ImageButton
        android:id="@+id/btnTint"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/btn_selector"

        />
...

android:tint: 设置的是颜色

android:tintMode:设置的是类型(src_in,src_over,src_atop,add,screen,multiply)

然后不管在xml布局中android:background,还是java代码setBackgroundResource,都可以直接使用成品背景图了。


参考资料
WebP 探寻之路

作者:ylyg050518 发表于2017/5/16 19:21:58 原文链接
阅读:119 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>