1.Tinker及其使用

一、热补丁

1.1 热补丁(hotfix)

热补丁:让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力。

热补丁技术可以理解为一个动态修改代码与资源的通道,它适合于修改量较少的情况。另外针对Android开发的机型碎片化问题,补丁机制也适合使用在远端调试上,即只需要具备给特定用户发送补丁的能力,对于查找问题非常有帮助。

二、Tinker

2.1 Tinker

Tinker是微信官方开发并采用的热补丁方案。支持dex文件、资源文件以及so文件的热更新。局限性在于无法支持AndroidManifest文件的修改。

Tinker是一个开源项目。

对于dex文件、资源文件以及so文件的更新,都是通过补丁生成,补丁合成以及补丁加载进行。如,针对dex文件,在编译时通过新旧两个dex文件生成差异patch.dex。在运行时,将差异patch.dex重新跟原始安装包的旧Dex还原为新的Dex。这样相较于直接替换dex文件,减少了文件包的大小。其中包含的主要技术就是patch.dex的生成算法以及dex的合成算法。微信使用的是自研的DexDiff算法。

2.2 Tinker的使用

Tinker开源项目中有tinker-sample-android项目作为示例。

由于在尝试集成过程中遇到各种问题,查阅各大论坛也有相应的问题但没有解决方案。因此,最后决定将tinker-sample-android中相关的配置进行copy,并进行适配,最终结果是能够成功生成差分包

2.2.1 拷贝相关文件

将tinker-sample-android项目中的如下文件拷贝到自己项目中:

app目录下的build.gradletinker_multidexkeep.pro

项目根目录下的build.gradlegradle.properties文件

2.2.2 增加相应patch

gradle.properties文件:

+ TINKER_ID=1.0
+ TINKER_ENABLE=true

build.gradle文件:

        implementation "androidx.multidex:multidex:2.0.1"

+        implementation 'androidx.appcompat:appcompat:1.0.0-alpha1'
+        implementation 'androidx.constraintlayout:constraintlayout:1.1.2'

上述操作之后,已经能够集成Tinker的相关功能。

2.2.3 将项目的Application类修改为SampleApplicationLike类

原因在于,Tinker的主要工作流程如图所示:

程序启动时会加载默认的Application类,由此导致无法在应用启动前加载补丁包。因此,Tinker中将Application类移除并将相应的代码放到ApplicationLike类中。

因此,在集成时,需要将注册的Application类修改为如下的形式:

@DefaultLifeCycle(
        application = ".SampleApplication",     //需要与注册的Application名字相同
        loaderClass = "com.tencent.tinker.loader.TinkerLoader",
        flags = ShareConstants.TINKER_ENABLE_ALL,
        loadVerifyFlag = false)                                //tinkerFlags above
public class SampleApplicationLike extends DefaultApplicationLike {

    public SampleApplicationLike(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);
        TinkerManager.installTinker(this);
    }
}

其中,TinkerManager从项目中copy即可。

三、Tinker测试

3.1 生成基准包

点开Gradle,运行app/tasks/other/assembleDebug,会在build/baseApk下生成apk文件及R.txt基准文件。

3.2 修改代码

将build.gradle中的tinkerOldApkPath、tinkerApplyResourcePath字段改成3.1中生成的文件名

并且可以进行代码修改

3.3 生成差分包

修改代码完成后,运行app/tasks/tinker/tinkerPatchDebug生成差分包,文件位置为build/outputs/apk/tinkerPatch/debug/patch_signed.apk文件。

由此,Tinker集成成功。

Last updated

Was this helpful?