性能优化之APK减肥记

引言

​ 有那么一句话 <u>“一百遮百丑,一胖毁所有”</u> ,这句话用在我们开发的应用程序上也不为过。为什么会这样说呢?

1.应用程序如果太大,用户下载耗时比较久,占用的流量也大 ,安装速度也就慢,这样用户很容易放弃使用;

2.这么胖的应用程序在运行过程中需要加载的资源和程序都很多,会导致加载速度慢,影响用户使用体验;

3.胖的应用也会在后续的项目维护中造成比较大的麻烦,例如:胖会引起比较多的疾病一样;

​ 看来我们对自己开发的应用程序制定一个减肥方案是有必要的,但是在制定方案之前,我们就得像医生一样,对其的构成和胖的原因进行全面的掌握,然后才知道如何制定减肥方案。

1)先来了解一下应用程序的组成结构:

APK文件结构

assets目录: 用于存放需要打包到APK中的静态文件,不参与编译,仅拷贝,可以使用AssetManager来检索这些资源;

res目录: 包含未编译到resources.arsc文件中的资源,如:图片,音视频文件等;

resources.arsc: 包含已经编译的资源,如anim 、array、String 、color、raw、style、xml、attr、drawable、menu等等;

lib目录: 包含用于特定处理器软件层的编译的代码,也就是兼容不同平台的类库,常见的有:armeabi,armeabi-v7a ,arm-v8a ,x86,x86_64 和mips;

classes.dex,classes2.dex,classes3.dex: 这些文件包含的就是编译后生成虚拟机认识的dex文件格式的类;

META_INF/: 包含的是签名文件(CERT.SF, CERT.RSA).清单文件MAINFEST.MF,已经一库文件的应用索引

AndroidManifest.xml: 包含核心的Android清单文件,有应用名称,版本,访问权限和应用哭等

分析“胖”的起因:

  1. 将apk包修改后缀为.zip 文件,解压后查看
  1. 使用android studio自带的Analyze APK工具(菜单Build---> Analyze APK--->选择你要分析的apk ,或者直接在android studio工程中直接双击你要分析的apk)
  1. Analyze App Size 插件(安装插件后就可以了,不过笔者在4.1.1的android studio上没有使用成功)

2)“减肥”方案

2.1 资源缩减减肥法

在你应用的build.gradle文件中,添加如下的配置:

android{
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }    
}  

资源缩减器shrinkResources在Gradle打包的时候可以自动忽略未使用的资源,但是他必须配合minifyEnabled才能发挥出来,代码缩减器minifyEnabled移除所有的代码后,资源缩减器才能知道哪些资源继续使用。

2.2 使用Lint静态代码分析器减肥法

菜单Analyze--->选择Run inspection by name ,然后会弹出如下图:(输入unused...)--->选择module或project ,lint 就开始帮你分析了。。。。

run_inspection_by_name

分析完成后,会展示在Inspection Results的窗口中,如下所示:

分析结果

点击左侧的一个文件后,

减肥行动图

注意:

  1. 不会扫描assets文件夹下的资源,
  1. 不会扫描通过反射应用的资源或已链接至应用的库文件
  1. 最后的删除是直接删除文件

2.3 一键移除无用资源减肥法

菜单Refactor--->Remove Unused Resource...---->选择preview 来查看有哪些资源,如下图:

一键移除无用资源preview

确保资源是确实没有使用,点击Do Refactor 直接移除,但是这个方式有个严重的问题就是针对动态获取资源id的方式会被认为没使用过,从而导致删除会引起错误,那么我们可以用下面的方法来解决:

在res/raw/文件夹中新建一个keep.xml的文件,该文件用来声明哪些资源要保留,哪些资源要舍弃。该文件是不会打包的apk中的。如下:

<?xml version="1.0" encoding="utf-8">
<resources xmlns:tools="http://schemas.android.com/tools"
    <!--声明保留的资源:多个资源用逗号隔开-->
    tools:keep="@layout/aaaaaa,@layout/bbbbbb,@drawable/ccccc"
    <!--声明放弃的资源-->
    tools:discard="@layout/ddddd"/>

以上资源缩减器只会删除代码没有引用的资源,但是他不会溢出用于不同设备配置的备用资源,我们可以使用grdle插件的资源配置属性溢出不需要的备用资源。比如我们的语言资源库,我们通过上面的分析器可以看到字符串资源包含了很多国家的语言,但是我们只需要其中的一两个语言的话,我们可以如下做:

android{
    //....
    defaultConfig{
        //......
         resConfigs "zh","en"
    }    
}
//这样就会只保存中文、英文、默认三个语言资源
资源限制配置

2.4 动态库打包配置减肥法

android{
    defaultConfig{
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters 'armeabi', 'x86', 'mips', "armeabi-v7a"
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
        }
    }
} 

我们在集成第三方库的时候,有些提供了全平台的cpu架构,我们就需要像上面一样添加很多库,但是在android系统中,每一个CPU架构对应一个ABI ,目前支持的有armeabi-v7a ,arm64-v8a ,x86等等。目前市场上的手机设备基本上都是arm架构了,armeabi-v7a 几乎能兼容所有的arm设备,所有我们可以修改上面的配置如下:

android{
    defaultConfig{
        ndk {
            //选择要添加的对应cpu类型的.so库。
            abiFilters  "armeabi-v7a"
            // 还可以添加 'x86', 'x86_64', 'mips', 'mips64','armeabi', 'x86', 'mips',
        }
    }
}

这样就只会将armeabi-v7a的动态库打包进apk ,这样可以缩写apk的大小。

​ 但是针对一些arm64的设备,我们用armeabi-v7a也可以兼容,但是性能方面就不如arm64的库,这样我们针对不同的设备可以提供不同架构的apk来安装。如下来实现:

//方案1
flavorDimensions "default"
productFlavor{
    arm32{
        dimension "default"
        ndk{
            abiFilters  "armeabi-v7a"
        }
    }
    arm64{
    dimension "default"
         ndk{
            abiFilters  "arm64-v8a"
        }
    }
}

//方案2
splits{
    abi{
        enable true
        reset()
        include "armeabi-v7a", "arm64-v8a"
        universalApk true  //是否将所有的so打包到一个apk中
    }
}

2.5 矢量图减肥法

​ 在我们的app中图片资源往往占用的空间都比较大,那么对这类图片资源的减肥能快速体现效果的时候。下面我们就分情况来处理一下:

1)使用webp格式的图片来替换jpg ,png格式的图片

​ 选择你要减肥的图片,点击右键,快捷菜单中选择convert to webp ,开始转换,如下图:


webp图片格式转换

点击“OK”,进入效果展示,如下图:


webp格式转换效果图

​ 可以看到我们这样就可以将一张5.2kb的图片转换为852byte大小的webp格式的图片,同样我们还可以调整Quality,然后finish按钮,这样就将我们需要优化的图片转换好了。

2)使用矢量图

​ 矢量图可以创建与屏幕分辨率无关的图标和其他可伸缩的媒体,在android中以VectorDrawable对象的形式来表示,不过系统在渲染每一个VectorDrawable对象的时候需要花费大量的时间,所有建议尽在小图片时使用这些矢量图。


创建矢量图

自定义矢量图

assetType: 可以选择系统的,可以加在本地的SVG ,PSD图

name可以定义为自己需要的名字。
​ 点击next---> 选择存放的目录---finish, 这样一张矢量图就创建成功了。

 <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints"/>

​ 给矢量图添加颜色:

<ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:tint="#ff0000"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints" />

​ 在selector中使用:

<!--定义selector:记得要放在color文件夹中作为颜色选择器-->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent"  android:state_pressed="true"/>
    <item android:color="@color/colorPrimary"/>
</selector>

<!--在imageView中使用: 用定义的颜色selector替换tint中的固定值即可-->
<ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:tint="@color/selector"
        android:src="@drawable/vector"
        tools:ignore="MissingConstraints" />

3)对于一些启动页,引导页等比较大的图片,建议使用jpg格式

好了,以上就是笔者工作中用过的一些减肥方法,如后续有更好的再来完善了。。。。。。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容