.dex资料更小并且拥有更好的运行时性能
涵盖java 8语言拥护的应对
利用方法(AS3.1默认)
gradle.properties android.enableD8=true
R8
和混淆类似,利用随机无意义的名称
内联 ,避免对象分配
在删除未利用的类 、字段、防范上更好
与相比 ,R8能使apk减小约10%,蓝莓外汇交易平台体积更小
利用方法
android.enableR8=trueandroid.enableR8.libraries=true
d 、移除无用代码
随着业务提升,许多之前利用的类可能并没有用到,然后又想着以后万一又能用到呢 ?反正就一个资料 ,删不删除无所谓,占内存又不大,长此以往 ,apk就越来越大了。
我平时都用 自带的 Lint 检查软件无效代码
慕课网的性能优化影片里讲到过一种计划,通过(简单入门)对某个包下的类就行构造函数切面
@After("execution(org.jay.launchstarter.Task.new(..)")public void newObject(JoinPoint point) { LogHelper.i(" new "+ point.getTarget().getClass().getSimpleName());}
感觉这个确实能打印出来利用的类 ,可以搜集起来 ,那还得写一个脚本找出没利用得类 ,删除 ,蓝莓市场外汇是不是正规的有点风险 。
我觉得还是倡导的计划简单有效,通过 插件 基于线上读者上报无用代码解读
2、资源瘦身
首先我们了解一下APK解压后 ,资源有关的目录
a、资源混淆
混淆优点
采用计划 微信的
b、无用资源删除
android{ .... buildTypes{ release{ shrinkResources trueminifyEnable true} }}
一般我们都会在build.里面配置上述代码,并通过 自带的Lint检查软件 进行 删除无用资源 ,这里注意,笔者流程流程中 ,发现用Lint检查出来的无用资源,很多其实都引用了的。FXTM富拓外汇
注意,这里配置 true 是真的将无用资源去除了吗 ?答案 :不是的
理由有两点
综上 ,所以说平台目前的这种做法并没有真正下降资料数目,.arsc、签名数据、以及ZIP资料数据依然没有改良 。
为什么平台不做删除呢 ?因为.arsc和R资料的资源ID默认是连续的 ,删除无用资源资料,资源ID会变更 ,这个时候代码中已经替换过的ID就会出现资源找不到的现状 ,所以只是替换成了空资料。
思路计划:删除资料,并且keep住R资料和.arsc中的ID
还有一种 ,利用 - 解读,具体可以查看
c、图像压缩
这个对比好实现,笔者将项目中大于10k的图像都压缩了一下,体积减小了3% ,笔记利用了cwebp 软件 ,转换成webp
# coding=utf-8import osfrom pathlib import Path'''file_directory : 目录modules : 变长参数 指定模块才解析'''def findAndConvert(file_directory, *modules): iflen(modules) == 0: print("modules must Designated") returniffile_directory.is_file(): print("this is a file , need a directory") returnifos.path.exists(file_directory): print("has this directory") forhomes, dirs, files inos.walk(file_directory): # print(homes)# print(dirs)# print(files)formodule inlist(modules): check_path = os.path.join(file_directory.absolute(), module) ifcheck_path inhomes: # print("============== convert this path " + check_path + " ================== ")# 寻找 src/main/res/darwable开头的资料# 或者直接找png jpg图像if"src\\main\\res"inhomes and "drawable"inhomes: # print(homes)forfile infiles: iffile.endswith(".png") or file.endswith(".jpg"): file_path = Path(os.path.join(homes, file)) iffile_path.is_file() and os.path.getsize(file_path.absolute()) >10 * 1024: # print(file)# print(file[:-4])current_file = os.path.join(homes, file) target_file = os.path.join(homes, file[:-4] + ".webp") cmd = "cwebp "+ current_file + " -o "+ target_file result = os.system(cmd) ifresult == 0: # os.remove(file_path.absolute())os.system("svn add "+ target_file) os.system("svn del "+ current_file) # else:# print("please check this path " + check_path) else: print("this directory has not exists")if__name__ == '__main__': path = Path("D:/WorkSVN/项目Prject/") # 指定包名 变长参数必填findAndConvert(path, "模块名","模块名2")
d、ECMarkets外汇代理资源资料规范化
3、SO瘦身
这个不多说了,直接上代码
defaultConfig { ndk { abiFilters "armeabi"}}
现在市面上大多都是架构,例如,微信APK解读一下 ,也能发现只有 ,虽然微信对启动做了CPU 架构的适配,什么时候启动的哪个so资料,都有适配。
具体可以了解 为何大厂APP如微信 、支付宝、淘宝 、手Q等只适配了-v7a/?
这里给出一个abi工作规则图
从图中可以得出另一个规则
三、进阶瘦身计划1 、代码瘦身
a 、三方库应对
其实这个都不能算做进阶瘦身计划 ,但在实际流程中,我确实没有想到对三方库进行应对,引发没必要的依赖启动进来的 ,毕竟将所有模块代码看一遍,很多模块不是自己写的,优化起来丢三落四的 ,所以放到进阶计划里了 。
在选择第三方库时 ,需要评审一下,以性能为第一指标 ,包体积为第二指标 ,尽量选择性能好,体积小的第三方SDK ,并且在利用到第三方SDK某个作用时,尽量继承某个作用依赖,而不是全部 ,例如只需要的某个webp作用 ,那就只集成webp依赖就好了。
我按照计划,将项目里所有依赖都过了一遍 ,发现图像有关Glide和都利用了,GG,并不能选择一个用 ,改动太大 ,涉及测试也很多,只能将这种计划在组内会议规范一下 。(PS :启动长图会呈现空白的)
b、去除debug数据与行号数据
dex资料架构图(摘自极客时间开发高手课包体积优化)
一般,我们都会在混淆配置中以下面的方法保留行号数据
-keepattributes SourceFile, LineNumberTable
如果不保留行号数据 ,dex大约可以下降5%的体积 ,但是Crash上报后 ,会拿不到行号怎么办?难题该怎么识别 ?同学 ,莫慌 ,支付宝 包大小极致压缩计划 帮你处理。
当然,支付宝这个计划是参考的的 ReDex ,这个只拥护linux、和mac 。因为我之前了解过ReDex ,所以在接到压缩体积包时,也调研过,可是编译阶段硬是没有编译过去 ,后面试了两次 ,还是有点难题 ,就没有利用该计划。
ReDex 有六个优点
c、Dex分包优化
上面讲到了ReDex的一个优点 ,基于反馈的Class字节码布局 ,这是啥意思呢?
类字节码在单个 Dex 中的布局是根据编译顺序而不是运行时行为决定,即便 会将 App 定义的组件以及部分开展需要的类放在 Main Dex 中,但依然不是根据运行时顺序布局 ,这会引发程序开展时需要查找随机分布在 Dex 中的类 。
ReDex 会将 APK 在 Lab 中试运行 ,并跟踪开展时哪些类需要启动,然后将这些类字节码放到 Dex 前部,下降开展时从闪存中寻找类的时间,从而提高 App 开展速度 。
好的 ,大致了解了,那你可能会问 ,这个跟Dex分包优化有半毛钱关系 ?
在我们利用分包后,此时的每一个Dex可能会调用到其它的Dex中的方法,这种跨Dex调用的方法会造成许多冗余数据,具体有两点
为了保证Dex有效率在80%以上 ,通过以下公式来衡量优化效果
Dex 数据有效率 = define methods数目 / reference methods 数目
为了实现上述所说的数据冗余去除,ReDex配置一下就可以
{ "redex": { "passes": [ "InterDexPass", "RegAllocPass"] }, "InterDexPass": { "minimize_cross_dex_refs": true, "minimize_cross_dex_refs_method_ref_weight": 100, "minimize_cross_dex_refs_field_ref_weight": 90, "minimize_cross_dex_refs_type_ref_weight": 100, "minimize_cross_dex_refs_string_ref_weight": 90 }, "RegAllocPass": { "live_range_splitting": false}, "string_sort_mode": "class_order", "bytecode_sort_mode": "class_order"}
d、Dex压缩
你可以解读一下 APP的dex资料,他把真正的代码放到了下面 ,引发只有一个700多kb的.dex,他通过XZ Utils将所有dex压缩成了一个 。
XZ 压缩算法 和 7-Zip 一样 ,内部利用的都是 LZMA 算法。对于 Dex 格式来说,XZ 的压缩率可以比 Zip 高 30% 左右。但是这套计划存在一些难题
上面的讲解摘自极客时间开发高手课 ,这里仅当了解了一下 ,因为还需要分平台适配,臣妾做不到 ,难度对于目前的我来说很高。
2 、资源瘦身
真正去除无用资源
利用 - 解读 ,具体可以查看
重复资源优化
这个在项目开展时就需要制定好规范,但是也避免不了,多个地方用到的图像或资源存放在不同的模块下 ,毕竟这是团队开发 。这个难题在使命开展流程中,确实不好搞,因为存在太多相同字符串,名称不同,文案一样,然后图像又有相同的,命名又不一样,难搞。
具体实行计划查看
3、SO瘦身
a、对的压缩与合并、裁剪
跟Dex一样,可以通过XZ Utils压缩
在默认的lib目录中,我们只需要启动少数开展流程有关的 ,其它放在第一次开展时解压。对于压缩率来说,可以比ZIP压缩高30% ,效果很好 。缺点和Dex类似
实行计划,配合采用的一个开源库
合并
在 4.3 之前,进程启动的数目是由限制的,可以打开查看
然后又出来计划了 和 Demo
裁剪
又是的计划
原理 :解读代码中的JNI方法以及不同方法调用 ,找到没有无用的导出 ,然后删除掉,这样在编译的时候也会把对应的无用代码并且删除掉 。
四、长效治理APK包体积
笔记一完结
发表评论