APK瘦身之九道工序

随着业务不断的增加,需求不断的迭代,我们的APP的体积也在不断的变大,越往后就越成长为一个庞然大物,此时开发者就需要关注到这个问题:如何在不影响使用功能的情况下精简APP的大小?还有就是。。。

我为什么没有从项目一开始就注意体积优化
image.png
1. SVG

Scalable Vector Graphics 可缩放矢量图,详情见谷歌官方文档
SVG不会像位图一样因为缩放而让图片质量下降,优点在于节约空间和内存,常用于小图标。

image.png

image.png

如果我们选择了Local file,使用了PSD文件,需要注意的是此时的SVG是不支持渐变和透明的。

如上图,我们选择了一张ic_android_black_24dp矢量图标,完成之后如下图


image.png

Android Studio为我们自动生成的xml代码

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>

svg是由xml定义的,标准svg根节点为<svg>,在Android中通过vector实现对svg的支持,根节点为<vector>获得一张SVG需要进行转换才能在Android当中使用。
如果想把机器人的颜色改为红色,只需要修改fillColor的值为FFFF0000即可。

批量转换SVG

Android Studio上单个转换SVG图像很方便,那么有多个SVG需要转化成Android的Vector,我们就需要借助第三方工具

具体的命令执行:

java -jar svg2vector-cli-1.0.0.jar -d . -o convert -h 20 -w 20

-jar jar文件路径
-d 指定SVG文件所在目录
-f 指定单个SVG文件
-h 设置转换后SVG的高
-w 设置转换后SVG的宽
-o 输出Android Vector图像目录
SVG兼容两种方式
image.png

app/build.gradle中添加

// 将SVG图片生成制定维度的png图片
vectorDrawables.generatedDensities('xhdpi','xxhdpi')
// 使用support-v7兼容
vectorDrawables.useSupportLibrary=true
implementation 'com.android.support:appcompat-v7:28.0.0'

布局中用法

app:srcCompat="@drawable/ic_netease"
2. Tint
3. 资源打包配置

resource.asrc
由于第三方库,如appcompat-v7的引入,库中包含了大量的国际化资源,根据业务情况可以通过配置删除

resConfigs 'zh-rCN' // 只保留中文资源
4. 动态库打包配置

如果项目中包含了第三方SDK或者自己使用了NDK,如果不进行配置会打包全CPU架构的动态库进apk,对于真机,只需要保留一个armeabi(armeabi-v7)就可以了。

ndk{
    abiFilters('armeabi', 'armeabi-v7')
}
5. 移除无用资源

Refactor -> Remove Unused Resources

一键移除,涉及到动态ID资源会出问题,所以不推荐使用。

Analyze -> Run Inspection by Name

键入Unused resources后,选中并执行

6. 开启代码压缩
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

其中,proguard-rules.pro文件内容为混淆代码,详见语法

-ignorewarnings

-dontskipnonpubliclibraryclassmembers

-keepattributes SourceFile,LineNumberTable

-keep class * implements java.io.Serializable {
    *;
}

-keep class **.R$* {*;}

#supportv4
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }

# fastjson
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.** { *; }
...
...
...
7. 启用资源缩减
shrinkResources true
8. 启用webp转换插件

webp格式是谷歌推出的一种有损压缩格式,这种图片格式相比png或者jpg的图片损失的质量几乎可以忽略不计,但是压缩后图片的体积比png或jpg要小很多,且质量没有明显损失。目前谷歌已经将这种压缩格式集成到了AS中,开发者能够很方便快捷的使用该插件。

选中需要转换的png图片右击,选择 Convert to WebP...

image.png

选择有损或无损编码。无损编码只在minSdkVersion大于等18可用。选择有损编码可以设置编码质量,并且可以勾选对转换后的图片在保存之前进行预览。
可以选择跳过如果转换后的图片大于原图和跳过包含透明通道的图片。因为AS只允许minSdkVersion大于等于18时创建透明度Webp图片,当minSdkVersion小于18会默认勾选跳过包含透明通道的图片。
9-patch图片不能转换为WebP图片。转换工具总是会自动跳过9-patch图片

9. 资源混淆和7zip压缩

资源混淆配合7zip压缩,减小apk大小,增加破解难度

通过resource.arsc文件格式,混淆步骤为
1. 解析arsc文件,主要为全局与资源名字符串池
2. 修改字符串池中的字符串,以无意义的a/b替换
3. 修改apk中的res目录资源文件名
4. 打包(7zip)、对齐、签名

可以使用微信团队开源的AndResGuard进行资源混淆
具体用法:
项目根目录下build.gradle中,添加插件的依赖

classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.15'

在app目录下,创建and_res_guard.gradle文件(也可以直接将内容写入build.gradle文件)

apply plugin: 'AndResGuard'
andResGuard {
    // mappingFile = file("./resource_mapping.txt")
    mappingFile = null
    use7zip = true
    useSign = true
    // 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字
    keepRoot = false
    whiteList = [
        // for your icon
        "R.drawable.icon",
        // for fabric
        "R.string.com.crashlytics.*",
        // for google-services
        "R.string.google_app_id",
        "R.string.gcm_defaultSenderId",
        "R.string.default_web_client_id",
        "R.string.ga_trackingId",
        "R.string.firebase_database_url",
        "R.string.google_api_key",
        "R.string.google_crash_reporting_api_key",

        // 我在实际项目中遇到第三方使用getIdentifier访问的资源的问题,将指定的资源放入白名单后,虽然不闪退了,但还是会出现无法理解的错误。所以只好全部id都放入白名单
         "R.id.*"
    ]
    compressFilePattern = [
        "*.png",
        "*.jpg",
        "*.jpeg",
        "*.gif",
    ]
    sevenzip {
         artifact = 'com.tencent.mm:SevenZip:1.2.15'
         //path = "/usr/local/bin/7za"
    }

    /**
    * 可选: 如果不设置则会默认覆盖assemble输出的apk
    **/
    // finalApkBackupPath = "${project.rootDir}/final.apk"

    /**
    * 可选: 指定v1签名时生成jar文件的摘要算法
    * 默认值为“SHA-1”
    **/
    // digestalg = "SHA-256"
}

在build.gradle文件中引用

apply from: 'and_res_guard.gradle'

集成完AndResGuard后,在app的gradle的tasks中,多了一个叫做andresguard的task

如果打debug包,执行resguardDebug指令;
如果打preview包,执行resguardPreview指令;
如果打release包,执行resguardRelease指令。

我们双击执行resguardRelease指令,执行完毕后,我们可以在app目录下的/build/output/apk/release/AndResGuard_{apk_name}/ 文件夹中找到混淆后的Apk

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

推荐阅读更多精彩内容