返回

Amigo Android热更新方案的再次解读

Android

序言

Amigo作为一个“过气”的的热修复框架,用来学习和了解一下热修复的基本原理还是很好的。本文是本系列的第三篇。

原作者已经很久没有更新的,我之前适配了Android8.0 和gradle3.0,最近适配的Android P。

我使用的是最新的环境Android Studio 3.5.0,配套的Gradle是5.0.1。

经过升级后的Amigo已经支持Android P了,由于已经在实际项目中使用,所以本文的适配仅供参考。在使用之前先仔细阅读,理解后使用。

正文

我们先看一下Android P中的两个新特性,一个是ARTProfile,这个是支持通过Profile文件来优化应用的,这个对于加固的app很有用,但热修复需要修改字节码,所以没有关系。

热更新和加固应该是一个组合拳,两个一起用,才能发挥威力。

另一个是statsd,这个工具可以对系统的服务,线程、cpu、内存等指标做采集,可以用来做性能调优。

两个特性与热修复没有太大关系,我们继续我们的优化。

在前面的章节中,我们已经适配了Android8.0,以及Gradle3.0,经过升级后的Amigo已经支持Android P了,由于已经在实际项目中使用,所以本文的适配仅供参考。

在使用之前先仔细阅读,理解后使用。

由于Android P适配的比较仓促,所以有很多细节,包括插件的一些实现细节,我没有完全测试,或者根本没法测试。

由于Amigo的插件化实现,非常依赖Gradle的一些配置,所以为了保证插件的正确生成,尽可能使用原作者提供的Gradle的配置,避免采用自定义Gradle。

包括旧版的,我也建议使用原作者的Gradle配置,然后根据项目自身的需要进行适当修改。

当然,这个适当需要开发者自己好好体会,我这里举几个具体的例子。

// task的配置
release {
  minifyEnabled true
  shrinkResources true
  proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

上面的代码在原作者的博客中是不存在的,这个是Gradle3.0中必须的,而且如果使用新的Android P的Studio,还有一些必须的配置项,比如说toolsVersion,我这里为了方便,就不一一列出了,配置方法和以前一样,到官网查看官方文档。

但插件生成的proguard.txt是有问题的,导致编译过不去。修改方法是在proguard.txt中把-dontpreverify改为-dontobfuscate,然后再把-dontnote添加到该文件中,就可以解决。

还要修改插件中DexTool的代码,在dex文件生成过程中,删除掉invocationLineReader的变量声明及初始化。

static void makeDexFile(DexOptions dexOptions, String inPath, String outPath,InvocationLineReader invocationLineReader)throws IOException {
  DexFileBuilder dexFileBuilder = new DexFileBuilder(dexOptions);
  registerClassesForMultiDex(dexFileBuilder);
  Visitor visitor = createVisitor(dexFileBuilder);
  Set<String> paths = new HashSet<String>(Arrays.asList(inPath.split(";")));
  for (String path : paths) {
    dexFileBuilder.loadDexFile(path, null, visitor, false);
  }
  File outFile = new File(outPath);
  dexFileBuilder.writeTo(outFile);
}

原作者的这句invocationLineReader是做什么的呢?

在开启MultiDex(也就是一个apk包含多个dex)时,会影响到try catch的定位。

这样改之后会更清晰,这里没有修复这个,因为这个跟热修复本身没有关系。

最后一步,修改 AmigoAgent.jar文件,其实就是把里边指定的Application的构造函数改成相应的构造函数,或者通过插件修改生成的文件,不改就没有什么效果。

修改原有的HotpatchApplication.java

@Override
public void onCreate() {
  super.onCreate();
  PackageManager mPm = getPackageManager();
  String apkPackageName = mPm.getPackageInfo(getPackageName(), 0).packageName;
  Amigo.init(getApplicationContext(), apkPackageName);
}

为支持Android P的验证,把super.onCreate()放在Amigo.init()之前,不然就验证不通过。

@Override
public void onCreate() {
  Amigo.init(getApplicationContext(), apkPackageName);
  super.onCreate();
}

由于市面上加固的apk太多,也导致了友商无法正常使用Amigo,不能为友商做嫁衣,因此代码开源后,包括dexmaker在内,很多类已经不在框架包中暴露了。

整个过程下来,还是比较曲折的,也暴露了不少问题,希望官方能多做适配,保证插件的兼容性。

目前在项目中使用起来还算比较稳定,但是性能需要进一步提升。

以上就是本次的全部内容了,本文除了指导读者如何将 Amigo 适配到 Android P 环境外,还讲解了一些技巧和注意事项,希望对大家有所帮助。