本文为大型面试分析,需要的可以点个关注
废话不多说,先来一张此系列文的面试资料目录
![7144f7f0811bbd61506f96e5578fbd2a.png](https://img-blog.csdnimg.cn/img_convert/7144f7f0811bbd61506f96e5578fbd2a.png)
1.热修复是什么
热修复无疑是这2年较火的新技术,是作为安卓工程师必学的技能之一。在热修复出现之前,一个已经上线的app中如果出现了bug,即使是一个非常小的bug,不及时更新的话有可能存在风险,若要及时更新就得将app重新打包发布到应用市场后,让用户再一次下载,这样就大大降低了用户体验,当热修复出现之后,这样的问题就不再是问题了。
目前较火的热修复方案大致分为两派,分别是:
1.阿里系:spohix、andfix:从底层二进制入手(c语言)。
2.腾讯系:tinker:从java加载机制入手。
2.有接触过tinker吗
答: 有接触过Tinker的 Tinker是一个比较优异修复架构
3.修复的原理是什么
答: 关于bug的概念自己百度百科吧,我认为的bug一般有2种(可能不太准确):
代码功能不符合项目预期,即代码逻辑有问题。
程序代码不够健壮导致App运行时崩溃。
这两种情况一般是一个或多个class出现了问题,在一个理想的状态下,我们只需将修复好的这些个class更新到用户手机上的app中就可以修复这些bug了。但说着简单,要怎么才能动态更新这些class呢?其实,不管是哪种热修复方案,肯定是如下几个步骤:
下发补丁(内含修复好的class)到用户手机,即让app从服务器上下载(网络传输)
app通过"某种方式",使补丁中的class被app调用(本地更新)
这里的"某种方式",对本篇而言,就是使用Android的类加载器,通过类加载器加载这些
修复好的class,覆盖对应有问题的class,理论上就能修复bug了。所以,下面就先来了解和分析Android中的类加载器吧。
4. Tinker源码分析
Tinker工程结构
直接从github上clone Tinker的源码进行食用如下:
![b14e3d00fd7d35c402bc7c8100c10c87.png](https://img-blog.csdnimg.cn/img_convert/b14e3d00fd7d35c402bc7c8100c10c87.png)
接入流程
1.gradle相关配置主项目中build.gradle加入
buildscript { dependencies { classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.8.1') }}
在app工程中build.gradle加入
dependencies { //可选,用于生成application类 provided('com.tencent.tinker:tinker-android-anno:1.8.1') //tinker的核心库 compile('com.tencent.tinker:tinker-android-lib:1.8.1') }......//apply tinker插件apply plugin: 'com.tencent.tinker.patch'
这里需要注意tinker编译阶段会判断一个TinkerId的字段,该字段默认由git提交记录生成HEAD(git rev-parse --short HEAD)而且是在rootproject中执行的git命令,所以个别工程可能在rootproject目录没有git init过,可以选择在那初始化git或者自定义gradle修改gitSha方法。
出包还是使用正常的build过程,测试阶段选择assembleDebug,Tinker产出patch使用gradle tinkerPatchDebug同样也支持Flavor和Variant,Tiner会在主工程build目录下创建bakApk,下面会有一个app-yydd-hh-mm-ss的目录里面对应有Favor子目录里面包含了通过assemble出的apk包。在build目录下的outputs中有tinkerPatch里面同样也区分了build variant产物。
![80b6d8d961605088be59a060302ce4c0.png](https://img-blog.csdnimg.cn/img_convert/80b6d8d961605088be59a060302ce4c0.png)
需要注意的是在debug出包测试过程中需要修改gradle的参数
ext { //for some reason, you may want to ignore tinkerBuild, such as instant run debug build? tinkerEnabled = true //for normal build //old apk file to build patch apk tinkerOldApkPath = "${bakPath}/app-debug-1018-17-58-54.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" //使用buildvariants修改此处app信息作为基准包 tinkerBuildFlavorDirectory = "${bakPath}/app-1020-11-52-37"}
而release出包可以直接在gradle命令带上后缀-POLD_APK= -PAPPLY_MAPPING= -PAPPLY_RESOURCE=
1.Application改造
Tinker采用了代码框架的方案来解决应用启动加载默认Application导致patch无法修复它。原理就是使用一个ApplicationLike代理类来完成原Application的功能,把所有原理Application中的代码逻辑移动到ApplicationLike中,然后删除原来的Application类通过注解让Tinker自动生成默认Application。
@DefaultLifeCycle(application = "com.*.Application