Android性能优化之Apk瘦身极致优化

1、SVG 可缩放矢量图
SVG不会像位图一样随着缩放而降低图片质量,优点在于节省空间与内存,多用于小图标。
svg是由 xml 文件定义的,根节点是 svg,但是在Android通过 Vector 对 svg 的支持,根节点是 vector ,获得一张 svg 需要先进行转换才能在android中使用。
Android性能优化之Apk瘦身极致优化_第1张图片
res——>new——>Vector Asset
Android性能优化之Apk瘦身极致优化_第2张图片
点开一看 哇 仿佛发现了新大陆,在这里我们可以拿到非常多,并且有意思的小玩意,同是我们可以导入本地的SVG、PSD格式的图片,
但是在这里要提醒,PSD 不支持 渐变 和 透明度
Android性能优化之Apk瘦身极致优化_第3张图片

比如说,我们来玩个飞机
Android性能优化之Apk瘦身极致优化_第4张图片

我们在xml文件中如何去使用这个矢量图呢?
Android性能优化之Apk瘦身极致优化_第5张图片
好,我们再回来,前面我们看到Android识别的是vector节点的,而我们本地的svg图片是 svg 节点的,所以我们不能够拿来直接用,难道我们要一个一个导入么?当然不是,我们有神器:
批量转换SVG
Android性能优化之Apk瘦身极致优化_第6张图片
我们使用这个jar包,可以实现批量生成我们Android中能够识别的节点的图片,使用时需要用cmd命令执行
具体的命令执行:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190328095054156.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmd5b25naGFvMTMy,size_16,color_FFFFFF,t_70)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兼容两种方式
Android性能优化之Apk瘦身极致优化_第7张图片
接下来我们看如何配置:

// 将SVG图片生成制定维度的png图片 (界限为5.0)
vectorDrawables.generatedDensities('xhdpi','xxhdpi')
// 使用support-v7兼容
vectorDrawables.useSupportLibrary=true

他们的兼容界限为5.0
Android性能优化之Apk瘦身极致优化_第8张图片
在这里插入图片描述

SVG很神奇的解决了套图(单套)的问题,500张不同分辨率的图精简100张,nice

2、Tint着色器
刚才我们说,解决一套图的优化,嘛呢多套图又该如何呢。下面我们就来说说tint属性
Android性能优化之Apk瘦身极致优化_第9张图片
Tint能够实现图片变色,利用tint显示不同颜色的图片,原本需要多张相同图片不同颜色的情况,能够减少apk的体积。
Android性能优化之Apk瘦身极致优化_第10张图片我们首先来实现静态的变色:
Android性能优化之Apk瘦身极致优化_第11张图片
Android性能优化之Apk瘦身极致优化_第12张图片

可以看出来我们直接设置tint属性即可,那么当然我们点击事件也是可以响应的了,请看小生继续分解:
不管你点击与不点击,图片都是一张,解决套图的根本,我们获取焦点之后改变颜色的配置请看下面
drawable文件配置
在这里插入图片描述
color文件配置
在这里插入图片描述
Android性能优化之Apk瘦身极致优化_第13张图片

点击事件能够响应,同时运用在其他控件上同样适用:
Android性能优化之Apk瘦身极致优化_第14张图片
选中事件的效果
在这里插入图片描述

3、资源配置

资源的映射文件,里面包含如下图所示的多种语言,我们在开发过程中可以干掉我们不需要的闲置资源,只保留我们需要的资源。
Android性能优化之Apk瘦身极致优化_第15张图片
那么这些语言怎么来的呢?——这些语言是由于v7包的引入。
在这里插入图片描述
那么假如说:我们在string.xml文件中有上百条,上千条数据 string ,那么每种语言就会有一整套这样的语言
在这里插入图片描述
针对上面这种情况,这个时候他的作用就非常大了:

//只保留指定和默认的资源
resConfigs ('zh-rCN','ko')

Android性能优化之Apk瘦身极致优化_第16张图片
那么我们又再次对APK进行了一次优化

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

ndk{
    abiFilters('armeabi', 'armeabi-v7a')
}
sourceSets{
        main{
            jniLibs.srcDirs=['libs']
        }
    }

这种方式可以极大降低APK的体积!
5、移除无用资源(物理删除)
一键移除如果出现使用动态id使用资源会出现问题
Android性能优化之Apk瘦身极致优化_第17张图片
这是没有用到的无用资源
我们说第一种方式:
Android性能优化之Apk瘦身极致优化_第18张图片
Android性能优化之Apk瘦身极致优化_第19张图片

这样就干掉了,直接从物理上的干掉。
第二种方式:
Android性能优化之Apk瘦身极致优化_第20张图片
Android性能优化之Apk瘦身极致优化_第21张图片
Android性能优化之Apk瘦身极致优化_第22张图片
Android性能优化之Apk瘦身极致优化_第23张图片

两种删除方式都是物理性的删除,是不可恢复的,都会直接干掉,效果如下图:
Android性能优化之Apk瘦身极致优化_第24张图片
虽说他的缺点有些不够人性化,但是效果还是很好的,可以有效清理我们开发过程中闲置的资源
所以提示 在使用之前,最好是先备份res资源文件;
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.** { *; }
...
...
...

附上一篇混淆很详细的语法介绍:https://www.jianshu.com/p/7e0a6faeb882
7、启用资源缩减

//启动资源压缩
shrinkResources true

Android性能优化之Apk瘦身极致优化_第25张图片
配置之后再次打包,进行对比
在这里插入图片描述
在这里插入图片描述
Android性能优化之Apk瘦身极致优化_第26张图片
Android性能优化之Apk瘦身极致优化_第27张图片

我们这种资源的压缩与第五种最大的不同,使我们保留了代码文件,只是不打包进入apk,这是灵魂的删除,值得使用。

8、启用webp转换插件
WebP (发音"weppy"),是一种同时提供了有损压缩与无损压缩的图片文件格式,这种图片格式相比png或者jpg格式的图片损失的质量几乎可以忽略不计,但是压缩后的体积却比png和jpg要小很多。
亲测一个1.7M的png图片经过webp转换之后可以压缩到小于100k,而且质量没有明显的损失。(大小是可调的)
目前谷歌已经将这种压缩格式集成到studio中
Android性能优化之Apk瘦身极致优化_第28张图片
Android性能优化之Apk瘦身极致优化_第29张图片
那么具体该怎么操作呢,嘿嘿
Android性能优化之Apk瘦身极致优化_第30张图片
哎呀,又get到了 ,好开心呀是不是,别着急,咱们还有哦

9、压缩对齐,res资源混淆(apk包)
资源混淆配合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

你可能感兴趣的:(Android性能优化之Apk瘦身极致优化)