上一篇介绍了And-fix热修复框架,但And-fix有它的局限性,现在介绍最近比较流行的一个热框架tinker。几个相关的链接,有助于快速了解。
1) 框架在github上的开源地址,https://github.com/Tencent/tinker;
2) tinker的历史,https://www.diycode.cc/topics/321
3) 微信Android热补丁实践演进之路http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=2649286306&idx=1&sn=d6b2865e033a99de60b2d4314c6e0a25#rd
下面介绍下tinker的继承教程,以当前tinker1.7.7版本为例:
一. 项目的根build.gradle 引入build 依赖
dependencies {
classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.7.7')
}
二.app module的build.gradle 引入编译依赖
dependencies {
//可选,用于生成application类
compile('com.tencent.tinker:tinker-android-anno:1.7.7')
//tinker的核心库
compile('com.tencent.tinker:tinker-android-lib:1.7.7')
compile('com.android.support:multidex:1.0.1')
}
三.app需要下载patch文件到sdcard,以及read操作,需要读写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
四、复制官方sample工程app/build.gradle中的其他相关配置到自己的app/build.gradle中
五、使用Tinker的要求自定义Application类,这一块需要特殊说明一下,tinker为了达到修改应用自己的Application的目的,使用代码框架封装继承DefaultApplicationLike的方式来实现对Application的修改,主要为了减少反射的使用和提高兼容性,具体说明参考 Tinker Wiki。
怎样实现自己的Application类呢,主要还是参考Tinker推荐的方式,通过注解生成Application类。
5.1 写一个继承自DefaultApplicationLike 的子类,例如SampleApplicationLike。并实现默认构造方法。
5.2 在SampleApplicationLike中添加如下注解,代码如下:
@DefaultLifeCycle(
application = "com.geepi.tinkerhotfix.application",
flags = ShareConstants.TINKER_ENABLE_ALL)
public class TinkerHotFixApplicationLike extends DefaultApplicationLike {
public TinkerHotFixApplicationLike(Application application, int tinkerFlags,
boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime,
long applicationStartMillisTime, Intent tinkerResultIntent) {
super(application, tinkerFlags, tinkerLoadVerifyFlag,
applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
}
@Override
public void onBaseContextAttached(Context base) {
super.onBaseContextAttached(base);
MultiDex.install(base);
TinkerInstaller.install(this);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
getApplication().registerActivityLifecycleCallbacks(callback);
}
}
六、找个地方加载补丁,我们这里为了演示,点击按钮进行加载补丁
findViewById(R.id.main_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
update();
}
});
七、测试
7.1 在build了有bug的项目后,apk会安装到手机上;同事在build/bakApk目录下会有一个这样的文件产生,app-debug-0308-16-08-14.apk
7.2 使用app-debug-0308-16-08-14.apk 字符串复制到build.gradle里头的tinkerOldApkPath 和tinkerApplyResourcePath
7.3 修改修复后的代码:
//修改之前的代码
private void showToast() {
Toast.makeText(this, "打补丁之前", Toast.LENGTH_LONG).show();
}
//修改之后的代码
private void showToast() {
Toast.makeText(this, "打补丁之后", Toast.LENGTH_LONG).show();
}
7.4 好了, tinker到这里就配置好了, 下面开始打补丁,开始打补丁包
命令行如下:
1)打debug补丁: ./gradlew tinkerPatchDebug
2)打release补丁: ./gradlew tinkerReleaseDebug
这里需要注意, 命令在linux和mac下最好是./gradlew, 意思是当前项目的gradlew, 如果写成gradlew可以会去下载gradle等, 因为那是全局的, 比如AS2.2.2带的版本是2.14.1
而我现在的是最新版本3.2.1, 可输入./gradlew -v 和 gradlew -v 查看
而windows就可以是gradlew
注意 debug和release配置的基包不同, 和他们一一对应, 另外, release还需要配置mapping文件.