当前位置:首页 > 经验 >

扫描件太大怎么缩小到1m以下(扫描件扫出来太大怎么改小)

来源:原点资讯(www.yd166.com)时间:2022-10-26 12:33:48作者:YD166手机阅读>>

本文作者:冯瑞;廖斌斌;刘丰恺

前言

应用安装包的体积会显著影响应用的下载速度和安装速度,按照 Google 的经验数据,包体积每增加 1M 会造成 0.17%的新增折损。抖音的一些实验也证明了包体积会显著影响下载激活的转化率。

Android 的安装包是 APK 格式的,在抖音的安装包中 DEX 的体积占比达到了 40%以上,所以针对 DEX 的体积优化是一种行之有效的包体积优化手段。

DEX 本质上是由 java/kotlin 代码编译而成的字节码,因此,针对字节码进行业务无感的通用优化成为我们的一个探索方向。

优化结果

终端基础技术团队和抖音基础技术团队在过去的一年里,利用 ReDex 在抖音包体积优化方面取得了一些明显的收益,这些优化也被同步到了其他各大 App 上。

在抖音、头条和其他应用上,我们的优化对 APK 体积的缩减普遍达到了 4%以上,对 DEX 体积的缩减则可以达到 8% ~ 10%

优化思路

在 android 应用的构建过程中,Java/Kotlin 代码会先被编译成 Class 字节码,在这个阶段 gradle 提供了 Transformer 可以进行字节码的自定义处理,很多插件都是在这个阶段处理字节码的。然后,Class 文件经过 dexBuilder/mergeDex 等任务的处理会生成 DEX 文件,并最终被打进安装包中。整个过程如下所示:

扫描件太大怎么缩小到1m以下,扫描件扫出来太大怎么改小(1)

所以,针对字节码的优化是有 2 个时机可以进行的:

  1. 在 transformer 阶段对 Class 字节码进行优化
  2. 在 DEX 阶段对 DEX 文件进行优化

显然,对 DEX 进行优化是更理想的一种方式,因为在 DEX 文件中,除了字节码指令外,还存在跨 DEX 引用、字符串池这样的结构,针对这些 DEX 格式的优化是无法在 transformer 阶段进行的。

在确定了针对 DEX 文件进行优化的思路后,我们选择了 facebook 的开源框架 ReDex 作为优化工具,并对其进行了定制开发。

选择 ReDex 的原因是它提供了丰富的基础能力,ReDex 的基础能力包括:

  1. 读写及解析 DEX 的能力,同时可以在一定程度上读取并解析 xml 和 so 文件
  2. 解析简单的 Proguard keep 规则并匹配类/方法/成员变量的能力
  3. 对字节码进行数据流分析的能力,提供了常用的数据流分析算法
  4. 对字节码进行合法性校验的能力,包括寄存器检查、类型检查等
  5. 一系列的字节码优化项,每项优化称为一个 pass,多个 pass 组成 pipeline 对 DEX 进行优化

扫描件太大怎么缩小到1m以下,扫描件扫出来太大怎么改小(2)

我们基于这些能力进行了定制和扩展,并期望最终建立完善的优化体系。

优化项

在抖音落地的优化项,包括 facebook 开源的优化和我们自研的优化,从其出发点来看,可以大致分为下面几种:

  • 通用字节码优化:通常意义下的编译优化,如常量传播、内联等,一般也可在 Transformer 阶段实现
  • DEX 格式优化:DEX 中除了字节码指令外,还包括字符串池、类/方法引用、debug 信息等等,针对这些方面的优化归类为 DEX 格式优化
  • 针对编程语言的优化:Java/Kotlin 的一些语法糖会生成大量字节码,可以对这些字节码进行针对性的分析和优化
  • 提升压缩率的优化:将 DEX 打包成 APK 实质上是个压缩的过程,对 DEX 内容进行针对性的优化可以提升压缩率,从而产生体积更小的 APK

这几种优化没有明确的标准和界线,有时一个 Pass 会涉及到多种,下面详细介绍一下各项优化。

通用字节码优化ConstantPropagationPass

该 Pass 实际上包含了常量折叠和常量传播。

常量折叠是在编译期简化常量的过程,比如

1 y = 7 - 14 / 2 2 ---> 3 y = 0

常量传播是在编译期替代指令中已知常量的过程,比如

1 int x = 14; 2 int y = 7 - x / 2; 3 return y * (28 / x 2); 4 ---> 5 int x = 14; 6 int y = 7 - 14 / 2; 7 return (7 - 14 / 2) * (28 / 14 2);

上面的例子经过 常量折叠 常量传播优化后就会简化为

1 int x = 14; 2 int y = 0; 3 return 0;

再经过死代码删除就可以最终变为return 0。

具体的优化过程是:

  1. 对方法进行数据流分析,主要针对 const/move 等指令,得出一个寄存器在某个位置可能的取值
  2. 根据分析的结果,进行指令替换或指令删除,包括:
  • 如果值肯定是非空的,可以将对应的判空去掉,比如 kotlin 生成的 null check 调用
  • 如果值肯定为空,可以将指令替换为抛空异常
  • 如果值肯定让某 if 分支走不到,可以删除对应的分支
  • 如果值是固定的,可以用 const 指令替换对应的赋值或计算指令

一个方法经过 ConstantPropagationPass 优化后,可能会产生一些死代码,比如例子中的int y = 0,这也为后续的死代码删除创造了条件。

AnnoKillPass

该 Pass 是用来移除无用注解的。注解主要分为三种类型:

  • SOURCE:java 源码编译为 class 字节码就不可见,此类注解一般不用过于关注
  • CLASS:字节码通过 dx 工具转成 DEX 就不可见,代码运行时不需要获取信息,所以一般来说也不需要关注,实测发现部分注解仍然存在于 DEX 中,这部分注解可以进行优化
  • RUNTIME:DEX 中仍然可见,代码运行中可以通过 getAnnotations 等接口获取注解信息,但是随着业务的迭代,可能获取注解信息的代码已经去掉,注解却没有下掉,这部分注解会被 ReDex 安全的移除

除此之外,实际上为了支持某些系统特性,编译器会自动生成系统注解,虽然注解本身是 RUNTIME 类型,但是可见性是VISIBILITY_SYSTEM

  • AnnotationDefault : 默认注解,不能删除
  • EnclosingClass : 当前内部类申明时所在的类
  • EnclosingMethod : 当前内部类申明时所在的方法
  • InnerClass : 当前内部类名称
  • MemberClasses : 当前类的所有内部类列表
  • MethodParameters : 方法参数
  • Signature : 泛型相关
  • Throws : 异常相关

举例说明

扫描件太大怎么缩小到1m以下,扫描件扫出来太大怎么改小(3)

编译器生成 1MainApplication$1这个匿名内部类,带有 EnclosingMethod 和 InnerClass 注解

扫描件太大怎么缩小到1m以下,扫描件扫出来太大怎么改小(4)

首页 123下一页

栏目热文

如何设置扫描件的大小(扫描仪上如何设置扫描大小)

如何设置扫描件的大小(扫描仪上如何设置扫描大小)

扫描过程代码用之前,要修改一下变量 folder 指向的扫描目录,执行的时候,会在终端显示当前目录下的一级目录的大小和文...

2022-10-26 12:42:41查看全文 >>

扫描如何设置批量扫描(扫描仪如何批量扫描)

扫描如何设置批量扫描(扫描仪如何批量扫描)

分享最实在的玩机技巧,洞察最前沿的科技资讯!大家好,这里是手机科技园!我们在平时工作中,经常会用到电子文件,比如说,客户...

2022-10-26 12:32:53查看全文 >>

批量处理扫描件黑边(如何消除扫描件的黑边)

批量处理扫描件黑边(如何消除扫描件的黑边)

在工作和生活中,我们有时需要扫描文件,相信大家都会去打印店,其实在我们的手机上隐藏着一个扫描仪功能,很多人都不知道,今天...

2022-10-26 12:08:35查看全文 >>

如何让扫描件更清晰(怎么让扫描仪扫描文件更清晰)

如何让扫描件更清晰(怎么让扫描仪扫描文件更清晰)

细节!1、目录一定要编制正确、完全;2、对应的页码一定要弄好,务必让专家在看到目录以后直接能定位到相应的页面;3、项目管...

2022-10-26 12:18:51查看全文 >>

如何批量修正歪斜的扫描件(如何批量把扫描文件修正)

如何批量修正歪斜的扫描件(如何批量把扫描文件修正)

1佳能DR-2020U回顶部【PConline 海选导购】对于文印社、学校、培训中心等机构,批量扫描文件的需求十分迫切。...

2022-10-26 12:26:27查看全文 >>

扫描件如何处理成指定大小(扫描件扫出来太大怎么改小)

扫描件如何处理成指定大小(扫描件扫出来太大怎么改小)

随着近年来三维数字化技术发展,已经有越来越多类型的客户会通过三维扫描仪来对各种尺寸、各种特征的工件进行测量与检测。当对细...

2022-10-26 12:50:37查看全文 >>

通过扫描修改尺寸实现片型修改(怎么修改扫描件上图片的长宽)

通过扫描修改尺寸实现片型修改(怎么修改扫描件上图片的长宽)

  先看看建模完成的效果。  模型树建模步骤。  草绘一个圆形,直径为100.  点击【插入】-【模型基准】-【图形】。...

2022-10-26 12:24:20查看全文 >>

扫描件太小放大变清晰(扫描件太大怎么缩小)

扫描件太小放大变清晰(扫描件太大怎么缩小)

一般来说,分辨率越高,呈现的图像、视频画面越清晰,很多视频平台都能够支持4K,甚至8K分辨率的视频。就4K分辨率来说,呈...

2022-10-26 12:32:34查看全文 >>

怎么控制扫描件大小(扫描图片尺寸太大怎么弄小)

怎么控制扫描件大小(扫描图片尺寸太大怎么弄小)

广州奖“我与城市共成长”照片征集活动火热进行中作品入选就可获得证书、奖金、展出机会那么,要如何提高入选几率呢?投稿要求由...

2022-10-26 12:08:48查看全文 >>

怎么提高扫描件清晰度(怎样使扫描件变得清晰)

怎么提高扫描件清晰度(怎样使扫描件变得清晰)

各位拍照水平如何?大多数人可能拍人拍景可能不在话下,个个都是修图高手,拍文件呢?不求美,但注重清晰度的那种;或者是,扫描...

2022-10-26 12:37:12查看全文 >>

文档排行