Sophix,Tinker简介:
https://www.cnblogs.com/ldq2016/p/10449433.html
Tinker:
安装过程 https://blog.youkuaiyun.com/qq_22393017/article/details/82110343
Tinker和QQ空间方案最大的不同是,Tinker 下发新旧DEX的差异包,然后将差异包和旧包合成新dex之后进行dex的全量替换,这样也就避免了QQ空间中的插桩操作。以上就是tinker热修复中代码加载实现的原理了。
https://zhuanlan.zhihu.com/p/54781576
Tinker的热修复使用了ClassCloader的类加载机制,将修复的类放到dex 数组的前面
整个流程主要包含两部分: patch的合成(UpgradePatch.java)以及 Patch的安装(TinkerLoader.java)两部分,
TinkerDexLoader: 负责加载dex,将修复的类放到dex 数组的前面
TinkerResourceLoader: 负责加载resource, 反射调用AssetManager的addAssetPath,添加资源apk(resource.apk)
TinkerSoLoader: 负责加载so
patch的合成过程:https://yuqirong.me/2019/03/14/Tinker%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90(%E5%85%AD)/
收到Patch,启动TinkerPatchService(本质是一个IntentService),进行Patch的检验,合成 ,通过patch的MD5作为当前patch的version,如果version一致,则patch无变化,不需要合成
app进程启动时,通过TinkerLoader的tryLoad 加载已合成后的patch
tinker接入事项:
1 在gradle.property中配置如下:
#设为true,才可以执行patch打包,需要关闭instant run,默认打包时,需要更改 TINKER_ENABLE = false
TINKER_ENABLE = true
# VERSION_CODE 用于设置打基准包的版本号,每次打patch,需要根据当前的版本有必要的进行修改
VERSION_CODE = 220900
3 执行相应环境的tinkerPatch task,比如tinkerPatchDongmanQaforservice,patch生成目录为
app/build/outputs/tinkerPatch/dongman/当前环境/patch_signed_7zip.apk
4 tinker针对多一个base apk,可以多次修复,这需要保证base apk的 tinkerId一致,同时需要改tinker.gradle中的patchVersion的版本
5 tinker支持新增activity
tinker内部配置:
1 默认最大重试加载patch次数 5次,定义在UpgradePatchRetry.java
2 如果app冷启动时,联系发生3次crash,从app启动到crash时间小于10ms,tinker会清除patch。
逻辑定义在SampleUncaughtExceptionHandler.java
3 TinkerPatchListener 用来检查patch的合法性
4 TinkerPatchReporter 用来上报patch的解析过程中的每个阶段的状态
5 TinkerUpgradePatch 真正用来patch加载的过程
6 加载过程中的ErrorCode可参见 ShareConstants.java
参见ShareTinkerInternals.java 中的 checkSignatureAndTinkerID()
7 tinker针对多一个base apk,可以多次修复,这需要保证base apk的 tinkerId一致,同时需要求改tinker.gradle中的patchVersion的版本
8 tinker支持新增activity,采用了插件化原理,在androidManifest.xml 中插入坑位,startActivity时,用代理activity来启动新增的activity
原理可见:ComponentHotplug.java(hook AMS,) IncrementComponentManager.java (保存新增Patch的activity)
AMSInterceptHandler.java(拦截启动,用代理替换),MHMessageHandler(启动真正的targetActivity),PMSInterceptHandler.java(hook了PMS)
测试方面: 多机型(三星,华为,小米,oppo,vivio 测试),多个Android平台(android 4.2,5.0,6.0,7.0,8.0,9.0)
待确认: 目前没有开启加固模式,在360的加密渠道包上,能否修复成功?
从Android 9开始,华为9.0(PAR-AL00)手机,tinker可正常修复
tinker patch加载步骤:
第一次启动 1 解析patch,获取diffDex,2 dex 优化
日志如下:
(standard input):42473:09-16 16:30:33.512 2761 2761 D TinkerPatchUtils: path: /storage/emulated/0/patch_signed_7zip.apk exsit
(standard input):42477:09-16 16:30:33.512 2761 2761 D TinkerPatchUtils: can read: true , size: 17763
(standard input):42481:09-16 16:30:33.515 2761 2761 D TinkerPatchUtils: path: /data/user/0/com.naver.linewebtoon.cn/tinker/patch_signed_7zip.apk exsit
(standard input):42485:09-16 16:30:33.515 2761 2761 D TinkerPatchUtils: can read: true , size: 17763
(standard input):42489:09-16 16:30:33.516 2761 2761 D Tinker.TinkerPatchListener: onLoadInterpret path=/data/user/0/com.naver.linewebtoon.cn/tinker/patch_signed_7zip.apk
(standard input):42493:09-16 16:30:33.516 2761 2761 I Tinker.TinkerPatchListener: receive a patch file: /data/user/0/com.naver.linewebtoon.cn/tinker/patch_signed_7zip.apk, file size:17763
(standard input):42506:09-16 16:30:33.539 2761 2761 W Tinker.UpgradePatchRetry: onPatchListenerCheck retry file is not exist, just return
(standard input):42507:09-16 16:30:33.539 2761 2761 D Tinker.TinkerPatchListener: checkForPatchRecover returnCode=0
(standard input):42508:09-16 16:30:33.541 2761 2761 D Tinker.TinkerPatchListener: get platform:all
(standard input):42611:09-16 16:30:33.651 3487 3487 W Tinker.TinkerLoader: tryLoadPatchFiles: we don't load patch with :patch process itself, just return
(standard input):42652:09-16 16:30:33.664 3487 3487 D Tinker.DefaultAppLike: onBaseContextAttached:
(standard input):42660:09-16 16:30:33.671 3487 3487 I Tinker.TinkerPatchListener: application maxMemory:256
(standard input):42664:09-16 16:30:33.675 3487 3487 W Tinker.Tinker: tinker patch directory: /data/user/0/com.naver.linewebtoon.cn/tinker
(standard input):42668:09-16 16:30:33.676 3487 3487 I Tinker.Tinker: try to install tinker, isEnable: true, version: 1.9.2
(standard input):42672:09-16 16:30:33.679 3487 3487 I Tinker.TinkerLoadResult: parseTinkerResult loadCode:-1, process name:com.naver.linewebtoon.cn:patch, main process:false, systemOTA:false, fingerPrint:Xiaomi/sagit/sagit:8.0.0/OPR1.170623.027/8.7.5:user/release-keys, oatDir:null, useInterpretMode:false
(standard input):42676:09-16 16:30:33.679 3487 3487 W Tinker.TinkerLoadResult: tinker is disable, just return
(standard input):42680:09-16 16:30:33.679 3487 3487 I Tinker.DefaultLoadReporter: patch loadReporter onLoadResult: patch load result, path:/data/user/0/com.naver.linewebtoon.cn/tinker, code: -1, cost: 2ms
(standard input):42684:09-16 16:30:33.680 3487 3487 D Tinker.TinkerLoadReporter: onLoadResult loadCode=-1
(standard input):42688:09-16 16:30:33.680 3487 3487 W Tinker.Tinker: tinker load fail!
(standard input):42692:09-16 16:30:33.682 3487 3487 I Tinker.ComponentHotplug: method install() is not invoked, ignore ensuring operations.
(standard input):42694:09-16 16:30:33.682 3487 3487 D Tinker.DefaultAppLike: onCreate
(standard input):42698:09-16 16:30:33.686 3487 3515 I Tinker.DefaultPatchReporter: patchReporter onPatchServiceStart: patch service start
(standard input):42702:09-16 16:30:33.687 3487 3487 W Tinker.UpgradePatchRetry: onPatchRetryLoad