android revre view,Android热修复之微信Tinker使用初探

前几天,万众期待的微信团队的Android热修复框架tinker终于在GitHub上开源了。java

今天拿下来集成使用了一下,发现md上对集成使用的过程介绍的比较精简(后来发现wiki上面却是很详细,须要的同窗能够本身去看),这里记录一下我集成使用的过程。shell

1、集成api

我这里直接使用的是他1.6.2版本(1.6.0-1.6.3集成与使用的应该都相似,可是1.7.0以及之后,修改比较大,配置与使用略有不一样)自带的sample,导入到studio中。微信

2、初始化配置app

首先咱们须要在app/bulid.gradle中,设置tinkerId的值,不少人开始编译就报错,提示“tinkerId is not set!!!”,就是由于这个值没有设置。获取tinkerId走的框架

def gitSha() {

return 'git rev-parse --short HEAD'.execute().text.trim()

}

这个方法,也就是获取git最近一次commit的版本号,因此要是你的当前Project没有配置git,或者当前的Project尚未commit过,或者git没有加入到环境变量中,会获取不到该值。知道了原理,那解决方式就本身想了,我这里就直接写死,上面这个方法直接返回固定字符串。

---------------------------------------------------------------------------

补充:关于获取git提交版本号

git rev-parse --short HEAD这段代码主要是用来显示最近一次提交到远程仓库上revision的编号(相似于“b03b0c4”的字符串。我的对git命令行了解很少,若是有知道的大神麻烦指教一下)。

因此前面说的,除了环境变量配置好git(能够在命令行输入 git --version ,显示出了版本号,即是配置成功),再把你的项目与git关联起来,而且保证有一次commit记录,才能获取到该字符串。

我在使用sample时先直接写死了。正式应用到项目上时,能够根据本身的实际状况来配置该参数。

---------------------------------------------------------------------------------------------------

以后,咱们会看到Manifest.xml中,SampleApplication.java这个类报红找不到。这个并不影响,由于到时候咱们在编译的时候,tinker会为咱们生成SampleApplication.java这个类,而起做用的代码就是SampleApplicationLike.java类声明上面的

@DefaultLifeCycle(application = "tinker.sample.android.app.SampleApplication",

flags = ShareConstants.TINKER_ENABLE_ALL,

loadVerifyFlag = false)这段注解,咱们也能够把这段注解注释了,

自定定义一个SampleApplication类继承 TinkerApplication类,而后加入无参构造方法,获得的类为:

/**

* Created by anzyhui on 2016/9/26.

*/

public class SampleApplication extends TinkerApplication {

public SampleApplication(){

super(

//tinkerFlags, which types is supported

//dex only, library only, all support

ShareConstants.TINKER_ENABLE_ALL,

// This is passed as a string so the shell application does not

// have a binary dependency on your ApplicationLifeCycle class.

"tinker.sample.android.app.SampleApplicationLike");

}

}这些都是Tinker这边定好的规矩,我们得照着来(第二个参数中的".app"不要忘了,也就是路径不要搞错了),其中第一个参数表示支持修复的类型,有如下类型能够选:

public static final int TINKER_DISABLE = 0x00;

public static final int TINKER_DEX_MASK = 0x01;

public static final int TINKER_NATIVE_LIBRARY_MASK = 0x02;

public static final int TINKER_RESOURCE_MASK = 0x04;

public static final int TINKER_DEX_AND_LIBRARY = TINKER_DEX_MASK | TINKER_NATIVE_LIBRARY_MASK;

public static final int TINKER_ENABLE_ALL = TINKER_DEX_MASK | TINKER_NATIVE_LIBRARY_MASK | TINKER_RESOURCE_MASK;

从字面理解就知道什么意思了。

从新编译一下,通常也不会有问题,若是报类重复的异常的话,看看你是否是以前已经生成过了SampleApplication了,在\build\intermediates\classes\debug\tinker路径下对应的目录里,有的话,删掉再编译试下。

3、功能测试

(1)debug版本

先尝试debug版本

如今咱们模拟打包一个出现bug的版本。

再activity_main.xml中加入俩控件:

android:id="@+id/tvMessage"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/showInfo"

android:text="一切正常" />

android:id="@+id/btnBug"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_alignParentStart="true"

android:layout_below="@+id/tvMessage"

android:text="点击出现bug"/>

MainActivity中设置点击事件,点击btnBug时,tvMessage显示"出现bug了"文字。

打包生成apk

这时,在build/bakApk目录中,会生成一个apk和一个R.txt文件,R.txt的做用后面再讲。

apk运行至手机中,

点击点击btnBug按钮,显示:

好,如今来修复这个bug。

咱们在activity_main.xml中删除该“点击出现bug”按钮,增长“点击修复bug”按钮:

(PS:也就是修改了res文件)

固然了MainActivity中的代码中,也修改了点击事件,删除了“点击出现bug”按钮的点击事件,增长了“点击修复bug”按钮的点击事件。

点击按钮后,上方文本要显示“bug已经修复了”。

代码改好后,咱们须要配置一下前面提到了R.txt文件,这里面保存了每次编译获得的每一个res文件的id值。

具体配置就是,在app/build.gradle的ext部分,添加oldApk(也就是出现bug的那个apk)的信息:

ext {

//for some reason, you may want to ignore tinkerBuild, such as instant run debug build?

tinkerEnabled = true

//you should bak the following files

//old apk file to build patch apk

tinkerOldApkPath = "${bakPath}/app-debug-0927-11-47-21.apk" //这个是你出现bug的apk完整名称,app/build/bakApk目录下

//proguard mapping file to build patch apk

tinkerApplyMappingPath = "${bakPath}/" //暂未开启混淆,不用管

//resource R.txt to build patch apk, must input if there is resource changed

tinkerApplyResourcePath = "${bakPath}/app-debug-0927-11-47-21-R.txt" //若是你修复了res文件,须要指定你bug版本的R.txt文件

}而后,在studio的右上角,打开gradle,找到tinkerPatchDebug(我一直用的是debug签名,这个根据本身实际状况来)这个task,点击运行。就会在output目录下生成一个tinkerpatch目录,

在里面找到patch_signed_7zip.apk和patch_signed.apk,这就是咱们的差分包。

由于代码中指定的差分包路径为:

loadPatchButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");

}

});咱们就直接使用

patch_signed_7zip.apk,放到咱们的手机根目录,再打开app,点击LOAD PATCH,

提示咱们补丁加载成功,重启后生效。

这里,咱们须要杀掉本进程,再进入app,才能应用补丁包修复成功。

有朋友评论说本身也加载成功但无法修复,是否是按得返回键退出(返回键退出时是activity销毁,进程还在)。

杀进程后再进入,应该就能够修复成功了,若是不成功,把补丁包逆向一下,看看本身修复的部分有没有在里面。

重启后,注意看界面上的按钮是否是已经被替换,

按钮已经替换了,这里我已经点击了按钮,因此上方文本内容也提示修复成功。

(2)release版本+混淆

release版本整体使用方式与的bug版本相似,

每次打出正式包时,咱们应该备份好。

在打包前,修改app/build.gradle里的

/**

* task type, you want to bak

*/

//def taskName = "debug"

def taskName = "release"

tastName为release,minifyEnabled设置为true,

这样release打包时才会在bakApk下生成对应的apk,R.txt以及mapping文件。

以后的打包是同样的。

打差分包(补丁)的时候,咱们要作的,一样是,替换里面的属性:

ext {

//for some reason, you may want to ignore tinkerBuild, such as instant run debug build?

tinkerEnabled = true

//you should bak the following files

//old apk file to build patch apk

tinkerOldApkPath = "${bakPath}/app-release-0929-11-28-36.apk"

//proguard mapping file to build patch apk

tinkerApplyMappingPath = "${bakPath}/app-release-0929-11-28-36-mapping.txt"

//resource R.txt to build patch apk, must input if there is resource changed

tinkerApplyResourcePath = "${bakPath}/app-release-0929-11-28-36-R.txt"

}开启了混淆的话,就要设置bug版本release包的mapping文件,以保证两次映射一致。

一样,右侧gradle,点击tinkerPatchRelease。

我此次Gradle任务进行了好几分钟,当时还觉得是出错了,后来看了一下下图,

27437bcf804b45a7a866a9d996f17565.png

由于我是第一次打release包,因此在下载必要的jar包。

有运行慢的能够点进这里看看,是否是同样的状况。

差分包打包成功后,跟以前同样的操做,我这边测试成功没问题呢。

4、总结

以前研究过AndFix,主要是使用native方法,来修改出现bug的方法,虽然支持的系统版本也很广(2.3~7.0),可是具备必定的局限性,只能修改方法的内部实现,不支持新增方法,新增、修改为员变量等;而基于ClassLoader的各类实现,因为采用在字节码中在构造方法注入一段代码,防止被打上CLASS_ISPREVERIFIED标记,在dalvik中比较影响性能,并且支持系统也不全面,因此都不是特别的完美。并且他们都有一个缺点,不能修改资源文件。

此次Tinker的发布,打破了原有的性能问题,功能局限,实现了,支持对library、java类、res文件的修复,而且除了小部分版本的设备(wiki上说是部分三星api19版本),其余基本均可以覆盖到(yunOS另说)。相信在wx几位大神的维护下,tinker会愈来愈好。官方Tinker热补丁技术交流群:377388954

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值