#微信热修复框架Tinker 接入指南---------->
Tinker简介:By腾讯微信团队开发,技术原理简介(参见 [http://blog.csdn.net/tencent_bugly/article/details/52251319](http://blog.csdn.net/tencent_bugly/article/details/52251319))> > 特性:Tinker目前只支持热修复 (暂且不插件化&不支持加固 ->源自[http://blog.csdn.net/tencent_bugly/article/details/52251319](http://blog.csdn.net/tencent_bugly/article/details/52251319) Q18 Q22) > ## 1. Run官方Demo参考链接 :From简书 [http://www.jianshu.com/p/57264c770c12](http://www.jianshu.com/p/57264c770c12)Rrom Tinker官方Wiki [https://github.com/Tencent/tinker/wiki](https://github.com/Tencent/tinker/wiki)### 1.1 导入Sample工程下载完Tinker之后这里需要注意 在android studio 中点击 tinker-sample-android 项目导入就好了(不要导入别的,导入根目录会识别不了app module),最好设置项目 允许 VCS->git,并确定切换到master分支(比较稳定)
``请关闭Android Studio 的Instant Run !!!``![](http://p1.bqimg.com/524586/1eee6c96e53d1c0cs.png)将官方给出的Sample工程在AndroidStudio中打开.替换 ``ignoreWarning = false`` 为 ``ignoreWarning = true`` ~~(Tinker 1.6.x版本)首先一点,在app的build.gradle文件中找到**usePreGeneratedPatchDex = true ** 注释掉,然后找到 ** tinkerId = getTinkerIdValue()** 并将其替换成 ** tinkerId = "tinkerId" ** (必须替换不然编译报错,官方文档写到:在运行过程中,我们需要验证基准apk包的tinkerId是否等于补丁包的tinkerId。这个是决定补丁包能运行在哪些基准包上面,一般来说我们可以使用git版本号、versionName等等。),其中后面的值可以随意设置.~~.(见图1)![](http://upload-images.jianshu.io/upload_images/1983594-b8d613e59c627aee.png?imageMogr2/auto-orient/strip%7CimageView2/2)**图1**a86e73d8bdaffd99 ## 1.2 编译运行原版apk使用assembleDebug 任务(如下图)编译并生成debug apk
![](http://i1.piimg.com/524586/79d0c17ccbb71a6cs.png)
`` 这里注意 android studio run 按钮生成的apk可能不会加入签名,使用tinker插件生成补丁包时候回导致签名不一致问题,建议使用assembleXXX 任务生成基准包,而且直接run 还会导致(对照基准apk包和补丁apk发现补丁apk比基准apk大了1M多,查看log.text发现居然多了很多莫名其妙的图片 详见wiki issue:https://github.com/Tencent/tinker/issues/103 输出文件详解参见 官方wiki https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97``
此时Tinker会在工程的app/build/bakApk/目录下保存这个时间点打包好的apk文件(这里就是基准包---所谓基准包 就是未启用热修复的包),找到刚才生成的apk文件,复制其完整文件名,在app的build.gradle文件找到**tinkerOldApkPath**这一项设置,并将其设置为**tinkerOldApkPath = "${bakPath}/<刚才生成的apk文件名>"**(见图2)![](http://upload-images.jianshu.io/upload_images/1983594-6ac05e922d23ec57.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图2**
在build.gradle文件找到**tinkerApplyResourcePath**这一项设置,并将其设置为**tinkerApplyResourcePath = "${bakPath}/<刚才生成的apk文件名下面的txt文件>"** ``apk,R.txt,mapping.txt等反正backApk目录下面生成的东西和gradle中ext各项对应``形如 ``` tinkerOldApkPath = "${bakPath}/app-debug-1018-17-32-47.apk" //proguard mapping file to build patch apk tinkerApplyMappingPath = "${bakPath}/app-debug-1018-17-32-47-mapping.txt" //resource R.txt to build patch apk, must input if there is resource changed tinkerApplyResourcePath = "${bakPath}/app-debug-1018-17-32-47-R.txt" //only use for build all flavor, if not, just ignore this field tinkerBuildFlavorDirectory = "${bakPath}/app-1018-17-32-47" ```
## 1.3 修改源码 生成新版apk 补丁在MainActivity.java中,我们稍作改动,例如将R.string.test_resource对应的字符串资源的值修改(见图3),```I am in the base apk-->//原值I am in the patch apk//新值>```还可以在MainActivity中添加一行代码(见图3)``` Log.e(TAG, "i am on patch onCreate"); ```![](http://upload-images.jianshu.io/upload_images/1983594-592e11c1d5498df7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图3**你可以自行做出更多的改动(这也是我们需要热修复的原因),然后再Gradle脚本中找到'app:/tinker/tinkerPatchDebug'这条命令(见图4),双击运行,它将生成debug版的patch(补丁)apk文件. (有时tinkerPatchDebug任务耗时过长,可关闭任务再次执行一次)\![](http://upload-images.jianshu.io/upload_images/1983594-f4f3790493b3c08f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图4**运行完毕后,补丁apk文件所在位置见图5 ![](http://upload-images.jianshu.io/upload_images/1983594-98c8f4a47d7f5999.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图5**(官方wiki:签名后并使用7zip压缩的补丁包,也是我们通常使用的补丁包。但正式发布的时候,最好不要以.apk结尾,防止被运营商挟持。)将patch_signed_7zip.apk这个文件拷贝到Android设备的ExternalStorageDirectory()路径下(即SD卡目录下).文件的路径可以随意设定,只需在MainActivity中指明补丁Apk路径即可(见图6) ![](http://upload-images.jianshu.io/upload_images/1983594-ebdeda00112e7d04.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图6**## 1.4 安装热修复补丁 观察程序变化点击APP主界面中的LOAD PATCH加载补丁,提示成功后,点击KILL SELF结束当前进程(Tinker必须重启才能热修复成功),重新启动后,即可发现变化.可以看到,经过上述修改,原有Apk的应用启动后在Log中打印为(见图7)![](http://upload-images.jianshu.io/upload_images/1983594-8d98c7ad3a4fa8f1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图7**而应用补丁后,打印结果为(见图8):![](http://upload-images.jianshu.io/upload_images/1983594-15f9ed2b104b5767.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)**图8**# 2. Tinker Sample编译失败中的常见问题## 2.1. 网络情况不佳时,tinker插件所依赖的库或者插件缺失(如 com.tencent.mm:SevenZip 缺失) 1.1 原因:下载地址是https开头,导致下载不下来
1.2 解决办法:找到C盘用户目录下.gradle目录下的cache目录(形如 C:\Users\hasee\.gradle\caches)
删除该文件夹下所有文件以及文件夹然后将 根目录(Project:)build.gradle中把 ![](http://p1.bpimg.com/524586/e5d98bdfc7e6fd95s.png) 把``jcenter()`` 更改为
``` jcenter(){ url 'http://jcenter.bintray.com/' } ```
再重新编译。(相当于再次重新下载依赖)## 2.2. Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'. BSDiff$1.class解决办法: clean project## 2.3. Error:(9, 0) Your project path contains non-ASCII characters编译失败原因:工程目录处于中文路径下解决办法:不处于中文路径下就好了## 2.4 加载补丁时补丁加载失败补丁加载失败的原因很多,具体原因可以在logcat中查看,但是需要确保logcat的设置如下,否则tinker合成补丁日志输出获取不到![](http://i1.piimg.com/524586/203d4865b1c89356s.png)常见加载失败有签名校验的问题![](http://i1.piimg.com/524586/1cb16b12d7102ea8s.png)解决办法:注意不要搞混 tinkerPatchDebug gradle任务 和 tinkerPatchReleas gradle任务 对应生成的
patch_signed_7zip,debug签名就用 tinkerPatchDebug gradle任务 生成的 patch_signed_7zip
`` 这里注意 android studio run 按钮不会加入签名,使用tinker插件生成补丁包时候回导致签名不一致问题,建议使用assembleXXX 任务生成基准包``