移动APP质量优化框架 - Booster

项目地址:github.com/didi/booste…android

简介

Booster 是一款专门为移动应用设计的易用、轻量级且可扩展的质量优化框架,其目标主要是为了解决 APP 复杂度的提高而带来的性能、稳定性、包体积等问题。git

为何是 Booster?

质量优化是全部应用开发者都要面临的问题,对于 DAU 千万级的 APP 来讲,万分之一的崩溃率就意味着上千的用户受到影响,对于长时间在线的司机来讲,司机端 APP 的稳定性关乎着司机的安全和收入,因此更是不容小觑。github

随着业务的快速发展,业务复杂度不断提高,咱们开始思考:web

  1. 如何持续保证 APP 的质量?
  2. 当 APP 崩溃后,如何快速定位问题所属的业务线?
  3. 能不能在上线以前提早发现潜在的质量问题?
  4. 能不能对 APP 进行无侵入的全局质量优化而不须要推进各个业务线?

基于这些考虑,Booster 应运而生,通过一年多的时间不断打磨,Booster 成绩斐然。因为目前在质量优化方面基于静态分析的开源项目屈指可数,加上质量优化对于 APP 开发者而言门槛偏高,所以,咱们选择了将 Booster 开源,但愿更多的开发者和用户能从中受益。安全

功能与特性

动态加载模块

为了支持差别化的优化需求,Booster 实现了模块的动态加载,以便于开发者能在不使用配置的状况下选择使用指定的模块,详见:booster-task-allbooster-transform-allbash

第三方类库注入

Booster 在进行优化的过程当中,可能须要注入一些特定的类或者类库,为了解决注入类的依赖管理问题,Booster 提供了VariantProcessor SPI 让开发者能够轻松的扩展,请参考:ThreadVariantProcessor.kt#L12markdown

性能检测

APP 的卡顿率是衡量应用运行时性能的一个重要指标,为了能提早发现潜在的卡顿问题,Booster 经过静态分析实现了性能检测,并生成可视化的报告帮助开发者定位问题所在,以下图所示:多线程

com.didiglobal.booster.demo.MainActivity

其实现原理是经过分析全部的 class 文件,构建一个全局的 Call Graph, 而后从 Call Graph 中找出在主线程中调用的链路(Application、四大组件、ViewWidget等相关的方法),而后再将这些链路以类为单位分别输出报告。app

详见:booster-transform-lint框架

多线程优化

业务线众多的 APP 广泛存在线程过载的问题,而线程管理一直是开发者最头疼的问题之一,虽然能够经过制定严格的代码规范来归避此类问题发生,可是对于组织结构复杂的大厂来讲,实施起来成本巨大,而对于第三方 SDK 来讲,代码规范则有些力不从心。为了完全的解决这一问题,Booster 经过在编译期间修改字节码实现了全局线程池优化,并对线程进行重命名。

如下是示例代码:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        getSharedPreferences("demo", MODE_PRIVATE).edit().commit()
    }

    override fun onStart() {
        super.onStart()
        Thread({
            while (true) {
                Thread.sleep(5)
            }
        }, "#Booster").start()
    }

    override fun onResume() {
        super.onResume()
        HandlerThread("Booster").start()
    }
}
复制代码

线程重命名效果以下图所示:

Thread Renaming

详见:booster-transform-thread

SharedPreferences 优化

对于 Android 开发者来讲,SharedPreferences 几乎无处不在,而在主线程中修改 SharedPreferences 会致使卡顿甚至 ANR,为了完全的解决这一问题,Booster 对 APP 中的指令进行了全局的替换。

详见:booster-transform-shared-preferences

常量字段删除

不管是资源索引,仍是其它常量字段,在编译完成后,就没有存在的价值了(反射除外),所以,Booster 将对资源索引字段访问的指令替换为常量指令,将其它常量字段从类中删除,一方面能够提高运行时性能,另外一方面,还能减少包体积,资源索引(R)表面上看起来微不足道,实际上占用很多空间,以滴滴车主为例,资源索引相关的类就有上千个,进行常量字段删除后,减少了 1MB 左右。

详见:booster-transform-shrink

Toast Bug 修复

为了完全解决在 Android 7.1 中存在的bug: 30150688,Booster 对 APP 中的 Toast.show() 方法调用指令进行全局替换。

详见:booster-transform-toast

资源压缩

APP 的包体积也是一个很是重要的指标,在 APP 安装中,图片资源占了至关大的比例,一般状况下,图片质量下降 10%-20% 并不会影响视觉效果,所以,Booster 采用有损压缩来下降图片的大小,并且,图像尺寸越小,加载速度越快,占用内存越少。

Booster 提供了两种压缩方案:

  1. pngquant 有损压缩(须要自行安装 pngquant 命令行工具)
  2. cwebp 有损压缩(已内置)

两种方案各有优缺点,pngquant 的方案不存在兼容性问题,可是压缩率略逊于 WebP,而 WebP 存在系统版本兼容性问题,总的来看,有损压缩的效果很是显著,以滴滴车主为例,APP 包体积减少了 10 MB 左右。

另外,像 Android Support Library 中包含有大量的图片资源,并且支持多种屏幕尺寸,对于 APP 而言,相同的图片资源,保留最大尺寸的便可。以 Android Support Library 为例,去冗余后,APP 包体积减少了 1MB 左右。

详见:booster-task-compression

WebView 预加载

为了解决 WebView 初始化致使的卡顿问题,Booster 经过注入指令的方式,在主线程空闲时提早加载 WebView

除上以上特性外,Booster 还提供了一些辅助开发的功能,如:检查依赖项中是否包含 SNAPSHOT 版本等等。

快速入门

在 buildscript 的 classpath 中引入 Booster 插件,而后启用该插件:

buildscript {
    ext.booster_version = '0.4.3'
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "com.didiglobal.booster:booster-gradle-plugin:$booster_version"
        classpath "com.didiglobal.booster:booster-task-all:$booster_version"
        classpath "com.didiglobal.booster:booster-transform-all:$booster_version"
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.didiglobal.booster'
复制代码

而后经过执行 assemble task 来构建一个优化过的应用包:

$ ./gradlew assembleRelease
复制代码

构建完成后,在 build/reports/ 目录下会生成相应的报告:

build/reports/
├── booster-task-compression
│   └── release
│       └── report.txt
├── booster-transform-lint
│   └── release
│       ├── com
│       └── org
├── booster-transform-shared-preferences
│   └── release
│       └── report.txt
├── booster-transform-shrink
│   └── release
│       └── report.txt
├── booster-transform-thread
│   └── release
│       └── report.txt
└── booster-transform-toast
    └── release
        └── report.txt
复制代码
相关文章
相关标签/搜索