阅读需 5 分钟

【CoCollider】Android平台系统版本快捷适配工具

Android平台应用开发过程中,随着业务的复杂性增加,不免会用到一些非公开的API或应用适配或厂商系统适配,从而导致每个版本需要适配。

☞ Github ☜  ☞ Gitee ☜

如何快速找到已经发生变更的接口是个繁琐的工作(特别是随着支持的版本跨度大的工程),我们希望有一个自动查找对比的工具,可以快速的帮你找到那些API已经变更,CoCollider 应运而生。 CoCollider 已经在我们内部使用,极大提升我们系统适配效率,Android 15适配在即,现在分享给大家。

CoCollider同样适用于某些深度定制的应用版本适配。

项目已开源:

☞ Github:https://www.github.com/iofomo/fireyer ☜ 

☞ Github:https://www.github.com/iofomo/wing ☜ 

如果您也喜欢,别忘了给我们点个星。

01. 需求

对于系统的API,我们的需求是:

  1. 类是否还存在。
  2. 类的继承关系是否有变化。
  3. 类的成员属性是否有变化。
  4. 类的方法属性是否有变化。

对于开发工程师的工作量,首次需要在源码中添加注释标签,这个工作不可省略,却一劳永逸:

格式:
// @cocollider{SDK版本区间,可选(为空则每次都会匹配)}{类名,必选}{成员,可选(为空则忽略)}{方法,可选(为空则忽略)}

范例1:
// @cocollider{sdk=28}{class=android.utils.Abc}{field=abc}{method=test1}

范例2:(多版本区间,多方法,多成员)
// @cocollider{sdk=28-30,32,34-}{class=android.utils.Abc}{field=abc1,abc2}{method=test1,test2}

范例3:(方法和成员支持简单通配符,最多一个`*`)
// @cocollider{sdk=28-}{class=android.utils.Abc}{field=abc*,*aabc}{method=test*,*atest}
// @cocollider{sdk=28-}{class=android.utils.Abc}{field=*}{method=*}

范例4:(现有代码快速添加,将当前代码文件中的字符串全部解析为方法或成员,注意首字母大写)
// @cocollider{sdk=28-30,32,34-}{class=android.utils.Abc}{field=String}
// @cocollider{sdk=28-30,32,34-}{class=android.utils.Abc}{method=String}

02. 举个栗子

排查`ActivityThread`类中在Android 9和10和11,以及14(含)以后的版本中,成员`mServices`和方法`currentActivityThread`是否有变化
如:
// @cocollider{sdk=28-30,34-}{class=android.app.ActivityThread}{field=mServices}{method=currentActivityThread}
或:
// @cocollider{sdk=28,29,30,34-}{class=android.app.ActivityThread}{field=mServices}{method=currentActivityThread}

03. 配置运行

  1. 电脑安装wing

  2. 手机安装Fireyer,或集成CoCollider模块的应用。

  3. 执行扫描命令:

    # 命令格式:(默认支持 h/c/cpp/java/kt/aidl,也可以追加文件类型),path为必选,SDK版本为必选,ext为可选
    $ wing -cocollider scan {path} {sdk mini-sdk max} <ext>

    # 如:
    $ wing -cocollider scan /home/workspace 28-30
    # 如增加了txt文件的扫描:
    $ wing -cocollider scan /home/workspace 28-30 txt

    # 输出
    >>> cocollider-28.zip
    >>> cocollider-29.zip
    >>> cocollider-30.zip
  4. 若直接使用Fireyer则跳过此步骤直接出结果,若为自集成开发的应用,还需要将生成的标识文件传给CoCollider库。

04. 扫描结果

cocollider-28.zip压缩包中的文件结构为:

$ wing -tree

文件结构为:

class=android.app.ActivityThread
super=android.app.ClientTransactionHandler
source=xxx/com/xxx/system/SysClass.java,240

field=TRANSACTION_addPackageDependency
source=com/xxx/demo/DemoClass.java,142
source=com/xxx/module/ModuleClass.java,240

method=addPackageDependency
source=com/xxx/demo/DemoClass.java,142
source=com/xxx/module/ModuleClass.java,240

...

05. 生成结果

cocollider模块根据扫描本地代码标识文件生成当前系统API匹配结果:

文件不存在,则说明该类在当前版本已删除或已变更。 没有define内容,则说明该方法在当前版本中已删除或已变更。

class=android.app.ActivityThread
super=android.app.ClientTransactionHandler
source=xxx/com/xxx/system/SysClass.java,240

field=TRANSACTION_addPackageDependency
define=static final int TRANSACTION_addPackageDependency
source=xxx/com/xxx/demo/DemoClass.java,142
source=xxx/com/xxx/module/ModuleClass.java,240
...

method=addPackageDependency
define=public void addPackageDependency(java.lang.String) throws android.os.RemoteException
source=xxx/com/xxx/demo/DemoClass.java,142
source=xxx/com/xxx/module/ModuleClass.java,240

method=addPackageDependency
define=
source=xxx/com/xxx/demo/DemoClass.java,142
source=xxx/com/xxx/module/ModuleClass.java,240
...

06. 获取变更

方式1:通过执行wing命令

# wing -cocollider cmp {old} {new}
$ wing -cocollider cmp /home/workspace/cocollider-34.zip /home/workspace/cocollider-35.zip

# output
10 classes changed
21 fields changed
10 methods changed
>>> cocollider-cmp-34-35

方式2:文件中的fieldmethod均已排序,你也可以使用BeyondCompare等工具对比目录。