Android 质量优化工具 Booster实践

一、Booster概览
Booster https://github.com/didi/booster主要由 Transformer 和 Task 组成,Transformer 主要用于对字节码进行扫描或修改(取决于 Transformer 的功能),Task 主要用于构建过程中的资源处理,为了满足特异的优化需求,Booster 提供了 Transformer SPI and VariantProcessor SPI 允许开发者进行定制,以下是 Booster 的整体框架:
在这里插入图片描述

二、Booster功能
Performance detection | 性能检测
使用 Booster 可以发现潜在的性能问题,例如,在应用中调用可能阻塞 UI 线程或者主线程的 API,如:I/O API 等。详情请参见: booster-transform-lint。

Performance optimization | 性能优化
对于开发者来说,线程管理一直是个头疼的问题,特别是第三方 SDK 中的线程,过多的线程可能会导致内存不足,然而幸运的是,这些问题都能通过 Booster 来解决。

System bugs fix | 系统问题修复
例如全局性地修复 Android API 25 版本中 Toast 导致的崩溃。详情请参见:booster-transform-toast、booster-transform-shared-preferences.

Package size reduction | 应用瘦身
Such as image resources compression, r inline, etc.
如:资源压缩及冗余资源删除、资源索引内联。

2.1 booster-transform-shared-preferences SharedPreferences 优化
shared-preferences的commit的操作(有返回值),有可能阻塞ui线程。Booster对没有用到返回值的commit操作放到异步线程中,对应Transformer实现如下:

@AutoService(ClassTransformer::class)
class SharedPreferencesEditorTransformer : ClassTransformer {

    private lateinit var logger: PrintWriter

    override fun onPreTransform(context: TransformContext) {
        this.logger = context.reportsDir.file(Build.ARTIFACT).file(context.name).file("report.txt").touch().printWriter()
    }

    override fun onPostTransform(context: TransformContext) {
        this.logger.close()
    }

    override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
        if (klass.name == SHADOW_EDITOR) {
            return klass
        }

        klass.methods.forEach { method ->
            method.instructions?.iterator()?.asIterable()?.filterIsInstance(MethodInsnNode::class.java)?.filter {
                it.opcode == Opcodes.INVOKEINTERFACE && it.owner == SHARED_PREFERENCES_EDITOR
            }?.forEach { invoke ->
                when ("${invoke.name}${invoke.desc}") {
                    "commit()Z" -> if (Opcodes.POP == invoke.next?.opcode) {
                        // if the return value of commit() does not used
                        // use asynchronous commit() instead
                        invoke.optimize(klass, method)
                        method.instructions.remove(invoke.next)
                    }
                    "apply()V" -> invoke.optimize(klass, method)
                }
            }
        }
        return klass
    }

    private fun MethodInsnNode.optimize(klass: ClassNode, method: MethodNode) {
        logger.println(" * ${this.owner}.${this.name}${this.desc} => $SHADOW_EDITOR.apply(L$SHARED_PREFERENCES_EDITOR;)V: ${klass.name}.${method.name}${method.desc}")
        this.itf = false
        this.owner = SHADOW_EDITOR
        this.name = "apply"
        this.opcode = Opcodes.INVOKESTATIC
        this.desc = "(L$SHARED_PREFERENCES_EDITOR;)V"
    }

}

private const val SHARED_PREFERENCES_EDITOR = "android/content/SharedPreferences\$Editor"

private const val SHADOW_EDITOR = "com/didiglobal/booster/instrument/ShadowEditor"
public class ShadowEditor {

    public static void apply(final SharedPreferences.Editor editor) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
                @Override
                public void run() {
                    editor.commit();
                }
            });
        } else {
            editor.commit();
        }
    }

}

2.2 booster-task-list-permission
本模块用于显示本工程依赖的 AAR 中使用的 Android 权限列表。
在这里插入图片描述

三、Booster自定义Transformer

3.1 transformer-with-asm
https://github.com/boostersamples/transformer-with-asm

@AutoService(ClassTransformer::class)
class SampleAsmTransformer : ClassTransformer {

    override fun transform(context: TransformContext, klass: ClassNode) = klass.also {
        println("Transforming ${klass.className}: ")
        klass.fields.ifNotEmpty {
            println(klass.fields.joinToString("\n") {
                "  - " + it.name + ": " + it.desc
            })
        }
        klass.methods.ifNotEmpty {
            println(klass.methods.joinToString("\n") {
                "  - " + it.name + it.desc
            })
        }
    }

}

3.2 transformer-with-javassist
https://github.com/boostersamples/transformer-with-javassist

@AutoService(ClassTransformer::class)
class SampleJavassistTransformer : ClassTransformer {

    override fun transform(context: TransformContext, klass: CtClass) = klass.also {
        println("Javassist Transforming ${klass.name}: ")
        klass.fields.asList().ifNotEmpty {
            println(klass.fields.joinToString("\n") {
                "  - $it"
            })
        }
        klass.methods.asList().ifNotEmpty {
            println(klass.methods.joinToString("\n") {
                "  - ${it.name}${Descriptor.toString(it.signature)}"
            })
        }
    }

}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值