Android应用内存分析与优化 - 工具篇之ByteX

avatar
@海尔优家智能科技(北京)有限公司

上次在研究滴滴Booster框架的时候,又发现了一款字节开源的字节码框架ByteX,今天研究一下...

1. 介绍

ByteX由字节跳动抖音 Android 团队提供,官方说它是一个基于gradle transform api和ASM的字节码插件平台(或许,你可以把它当成一个有无限个插头的插座?)。

怎么理解字节码插件开发平台呢?官方在背景中举例说单独插件编译构建耗时是多少,加起来就会呈线性增长,而ByteX的思想是把插件的所有功能都做出来,但留出中间的feature部分,可自由扩展,这样就可以解决上述的问题,压缩构建时长,只用一个插件的构建时长或者多一点点,就可以完成N个插件的功能,另一方面形成平台后,可以加快开发进度,新增一个插件功能将会变得更加简单。

目前集成了若干个字节码插件,每个插件完全独立,既可以脱离ByteX这个宿主而独立存在,又可以自动集成到宿主和其它插件一起整合为一个单独的Transform。插件和插件之间,宿主和插件之间的代码是完全解耦的(有点像组件化),这使得ByteX在代码上拥有很好的可拓展性,新插件的开发将会变得更加简单高效。

2. 特点

  • 代码复用。公共的代码下沉下到common,给所有插件复用,这样每个插件就只需要专注于字节码插桩就行了。

  • 插件间代码隔离,相互解耦。之前字节码的相关feature都是基于某个字节码插件module来迭代扩展的,但各个feature的代码耦合在一起,久而久之这个插件module就成为了大杂烩。而基于ByteX,各个feature都独立成一个个插件,各个feature的代码相互隔离,相互独立,有利于新插件的功能拓展。

  • 平台化让transform更高效

    • class文件多线程并发处理,充分利用打包机的CPU资源。
    • 插件间自动无缝地整合成一个Transform,提高处理构建的效率。Transform过程中,对class文件的IO是比较耗时的,把所有的plugin整合成一个单独transform可以避免打包的额外时间开销呈线性增长。让耗时从1+1=2,变成1+1<2或者约等于1。
  • 插件移植性强。每个插件都可以脱离ByteX宿主,独立成一个transform,独立工作。

3. 项目结构

image.png

TransformEngine

负责遍历读取工程和Android SDK里的所有class文件,并回写到transform指定目录。

base-plugin

宿主,也就一个壳。

common

基础代码库,包括类图构建逻辑,日志,提供给各个插件的适配接口等。

其它插件module

依赖common,实现相应的接口和各自的字节码插桩逻辑。

4. ByteX框架能做什么?

在字节跳动公司内基于ByteX开发的插件超过25个(只开源了部分),我们可以将它开放出来的插件直接拿来用,将来也可以基于ByteX快速开发出自己的插件,可以完成的功能包括但不限于以下这些:

  • 性能优化(SPI...)
  • 优化包大小(xxx-inline...)
  • 修复bug
  • 代码分析检查/安全扫描
  • AOP(SharedPreferences替换...)
  • 其他

5. 接入方法

// 在build.gradle里添加以下配置,按需apply你的插件:

buildscript {
    ext.plugin_version="0.3.0"
    repositories {
        google()
        jcenter()
        maven {
            url "https://artifact.bytedance.com/repository/byteX/"
        }
    }
 
    dependencies {
        classpath "com.bytedance.android.byteX:base-plugin:${plugin_version}"
          // Add bytex plugins' dependencies on demand. 按需添加插件依赖
        classpath "com.bytedance.android.byteX:refer-check-plugin:${plugin_version}"
          // ...
    }
}
 
apply plugin: 'com.android.application'
// apply ByteX宿主
apply plugin: 'bytex'
ByteX {
    enable true
    enableInDebug false
    logLevel "DEBUG"
}
 
// 按需apply bytex 插件
apply plugin: 'bytex.refer_check'
// ...



// 注意:如果不apply ByteX宿主,那么这些ByteX插件与普通的插件无异,将会各自形成单独的Transform。反之,所有ByteX的插件将会自动融合成一个Transform。

6. 官方已有的插件

  1. 官方插件如下

    1. access-inline-plugin(access方法内联)
    2. shrink-r-plugin(R文件瘦身和无用资源检查)
    3. closeable-check-plugin(文件流的close检查)
    4. const-inline-plugin(常量内联)
    5. field-assign-opt-plugin(优化多余赋值指令)
    6. getter-setter-inline-plugin (getter和setter方法内联)
    7. method-call-opt-plugin(干净地删除某些方法调用,如Log.d)
    8. coverage-plugin(线上代码覆盖率)
    9. refer-check-plugin(检查是否有调用不存在的方法和引用不存在的字段)
    10. serialization-check-plugin(序列化检查)
    11. SourceFileKiller(删除SourceFile和行号属性,作为示例)
    12. ButterKnifeChecker(检测跨module使用ButterKnife可能导致的问题)
    13. RFileKnife(修复R.java太大编译报code too large的问题)
  2. 经验证,以下三个插件引入我们的工程后,可直接编译通过,总共减小包体伿360KB

    1. shrink-r-plugin
    2. const-inline-plugin
    3. field-assign-opt-plugin

7. 编译源码

7.1 关于维护

  1. 从Github上下载下来代码,查看提交记录,发现从2021年7月更新后就再没有新的代码提交,与它相对应的是booster一直有代码提交,难道又是一个KPI产品,开源就了事了,不再维护?
  2. 赶紧找了一个字节的朋友问一下,原来他们内部一直在用,说是必需品,看来应用还是挺强的啊,只是开源的有点差强人意,KPI产品确凿了,且用且珍惜吧,或者自己造一个轮子? ^_^

7.2 下载代码

  1. 官方开源在github上,地址是:github.com/bytedance/B…
  2. 直接Clone下来即可,没有杂七杂八的分支,只有一个master,最高发布版本是0.3.0
  3. 基于master拉一个dev分支进行开发

7.3 编译

  1. 修改Maven代理,加快依赖下载速度

image.png

  1. 运行脚本 bash publish.sh,即可将产物发布到代码根路径下的 gradle_plugins 目录下,或者双击uploadArchives 任务;

7.4 发布到公司Maven

1. 添加配置

如果我们的插件在本地开发并自测完成后,需要将插件发布到线上的公司maven,方便集成到实际项目的当中。首先在ByteX的根目录下新建(如果有就不用新建了)一个local.properties的配置文件,添加如下配置:

  UPLOAD_MAVEN_URL=xxx
  UPLOAD_MAVEN_URL_SNAPSHOT=xxx
  USERNAME=xxx
  PASSWORD=xxx
  USERNAME_SNAPSHOT=xxx
  PASSWORD_SNAPSHOT=xxx

2. 然后,修改ext.gradle里的upload_version

image.png

  1. 运行脚本发布

同样地,执行脚本(或者双击uploadArchives即可将插件发布到线上maven.)

./publish.sh -m

  发布到snapshot

./publish.sh -m -t

8. 总结 & 后续

本篇文章简单介绍了一下ByteX,及如何编译和发布它,在我本地已经成功编译,并发布到私服进行了验证,整体感觉ByteX的文档写和编译脚本写得还是挺完善的,比较容易上手。后续在ByteX框架上扩展新功能或者是其它的一些参考可以参考官方文档 github.com/bytedance/B…

参考

官方

团队介绍

三翼鸟数字化技术平台-定制平台开发」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。