基于Nuwa实现Android自动化HotFix

What–什么是HotFix

HotFix是针对某一个具体的系统漏洞或安全问题而发布的专门解决该漏洞或安全问题的小程序,通常称为修补程序

Why–为什么我们要用HotFix

试想这样一个场景:当Android发布App之后,如果突然发现了一个严重bug,而这个bug需要进行紧急修复

这时候我们通常的处理流程是:解决bug、重新打包App、测试、向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新发布。用户体验来很是糟糕

Question: 有没有办法不重新发布App,不需要用户重新下载覆盖安装,就可以完成Bug的修复?

答案是Yes,HotFix就是做这个事情的。Android HotFix原理介绍可以参照这里:HotFix

Nuwa(女娲)是一个自动化的工具,基于上述原理将骤自动化了,下面我就介绍一下如何使用

How–怎么用

添加Gradle Plugin

在工程的根build.gradle文件中添加

classpath ‘cn.jiajixin.nuwa:gradle:1.2.2’

然后我们的build.gradle文件可能长这样:

1
2
3
4
5
6
7
8
9
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'cn.jiajixin.nuwa:gradle:1.2.2'
}
}

添加Nuwa SDK

在app的build.gradle中添加依赖:

apply plugin: “cn.jiajixin.nuwa”

然后我们的build.gradle文件可能长这样:

1
2
3
4
5
6
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'cn.jiajixin.nuwa:nuwa:1.0.0'
}

【备注】 这边有个坑,2.0版本的Android Studio为了支持Instant Run, 默认使用的Gradle Plugin是2.0.0-alpha2, 如果用此版本,会报错Error:Cannot get property 'taskDependencies' on null object,乖乖降低到1.2.3,木有此问题

使用Nuwa

1.自定义Application,并且在Application类中添加如下代码:

1
2
3
4
5
6
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Nuwa.init(this);
Nuwa.loadPatch(this,"/sdcard/patch.jar")
}

2.运行并安装apk,会在app/build/outputs/目录下自动生成一个叫nuwa的目录:

拷贝此目录到一个指定的目录,比如:

/Users/Documents/nuwa

此apk目前是有bug的apk, 然后我们修复bug, 修复完毕后进入步骤3

3.在修复完bug的code base下执行如下命令:

./gradlew clean nuwaDebugPatch -P NuwaDir=/Users/Documents/nuwa

然后在app/build/outputs/nuwa/debug/目录下会自动生成patch.jar文件:

此文件就是我们热部署的补丁文件

4.我们把补丁文件拷贝到sdcard根目录(这边只是为了测试整个hotfix流程, 自己的项目肯定是放在服务器上,我们通过代码自己去下载和存储)

adb push app/build/outputs/nuwa/debug/patch.jar /sdcard/

5.重新启动app,Bug Fix😀

代码混淆

在proguard-rules.pro中添加:

-keep class cn.jiajixin.nuwa.* { ; }

我写了一个简单地例子用于演示,点此查看