热修复学习(3):Tinker组件依赖

上一篇热修复学习(2):TinkerSDK集成比较方便,但是补丁存在三方平台且更新受三方限制,这一篇的思路是在启动app时获取是否需要更新,然后下载并且加载补丁。

1.在项目的build.gradle中添加依赖
buildscript {
    dependencies {
        classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1')
    }
}
2.在app的gradle文件中添加配置

注意Tinker需要使用到MulitDex 所以要填MulitDex的依赖

//Gradle版本小于2.3的这么写
dependencies { 
compile "com.android.support:multidex:1.0.1" //可选,用于生成application类
provided('com.tencent.tinker:tinker-android-anno:1.9.1') //tinker的核心库   
compile('com.tencent.tinker:tinker-android-lib:1.9.1') }
//Gradle版本大等于2.3的这么写
dependencies { 
implementation "com.android.support:multidex:1.0.1" //tinker的核心库
 implementation("com.tencent.tinker:tinker-android-lib:1.9.1") { changing = true } //可选,用于生成application类   
annotationProcessor("com.tencent.tinker:tinker-android-anno:1.9.1") { changing = true } 
compileOnly("com.tencent.tinker:tinker-android-anno:1.9.1") { changing = true } }
//apply tinker插件
apply plugin: 'com.tencent.tinker.patch
defaultConfig {
        ...
        multiDexEnabled true
}
3.配置Tinker的设置

配置巨多请参考 build.gradle官方demo的gradle文件,这里只说一下会用到属性

ext { 
// 是否使用Tinker(当你的项目处于开发调试阶段时,可以改为false) 
tinkerEnabled = true 
// 基础包文件路径(名字这里写死为old-app.apk。用于比较新旧app以生成补丁包,不管是debug还是release编译) 
tinkerOldApkPath = "${bakPath}/old-app.apk" 
// 基础包的mapping.txt文件路径(用于辅助混淆补丁包的生成,一般在生成release版app时会使用到混淆,所以这个mapping.txt文件一般只是用于release安装包补丁的生成)
 tinkerApplyMappingPath = "${bakPath}/old-app-mapping.txt"
 // 基础包的R.txt文件路径(如果你的安装包中资源文件有改动,则需要使用该R.txt文件来辅助生成补丁包)
    tinkerApplyResourcePath = "${bakPath}/old-app-R.txt"
4.Tinker的自定义功能

Tinker官方文档:可选的自定义类
可以直接复制到项目中,一般只修改bug可能用不到这些,这里只做了解

《热修复学习(3):Tinker组件依赖》 image

可以从
Tinker的官方demo下拷贝

简单说明下,这几个文件的作用:

SampleUncaughtExceptionHandler:Tinker的全局异常捕获器。

MyLogImp:Tinker的日志输出实现类。

SampleLoadReporter:加载补丁时的一些回调。

SamplePatchListener:过滤Tinker收到的补丁包的修复、升级请求。

SamplePatchReporter:修复或者升级补丁时的一些回调。

SampleTinkerReport:修复结果(成功、冲突、失败等)。

SampleResultService::patch补丁合成进程将合成结果返回给主进程的类。

TinkerManager:Tinker管理器(安装、初始化Tinker)。

TinkerUtils:拓展补丁条件判定、锁屏或后台时应用重启功能的工具类。

5.Application的修改

修改是为了动态的修改Application类
代码如下

@SuppressWarnings("unused")
/// application类名。只能用字符串,这个MyApplication文件是不存在的,但可以在AndroidManifest.xml的application标签上使用(name)
@DefaultLifeCycle(application = "tinker.sample.android.app.SampleApplication",
                  flags = ShareConstants.TINKER_ENABLE_ALL,
                  loadVerifyFlag = false)
public class SampleApplicationLike extends DefaultApplicationLike {
    private static final String TAG = "Tinker.SampleApplicationLike";

    public SampleApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag,
                                 long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
    }

    /**
     * install multiDex before install tinker
     * so we don't need to put the tinker lib classes in the main dex
     *
     * @param base
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        //you must install multiDex whatever tinker is installed!
        MultiDex.install(base);

        SampleApplicationContext.application = getApplication();
        SampleApplicationContext.context = getApplication();
        TinkerManager.setTinkerApplicationLike(this);

        TinkerManager.initFastCrashProtect();
        //should set before tinker is installed
        TinkerManager.setUpgradeRetryEnable(true);

        //optional set logIml, or you can use default debug log
        TinkerInstaller.setLogIml(new MyLogImp());

        //installTinker after load multiDex
        //or you can put com.tencent.tinker.** to main dex
        TinkerManager.installTinker(this);
        Tinker tinker = Tinker.with(getApplication());
// 将之前自定义的Application中onCreate()方法所执行的操作搬到这里..
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
        getApplication().registerActivityLifecycleCallbacks(callback);
    }

}

《热修复学习(3):Tinker组件依赖》 图片.png

6.常用的Api

请求打补丁

TinkerInstaller.onReceiveUpgradePatch(context, 补丁包的本地路径);

卸载补丁

Tinker.with(getApplicationContext()).cleanPatch();// 卸载所有的补丁
Tinker.with(getApplicationContext()).cleanPatchByVersion(版本号)// 卸载指定版本的补丁

Hack方式修复so

TinkerLoadLibrary.installNavitveLibraryABI(this, abi);
7.测试

打补丁方式与上一篇类似,测试的时候可以用下面的命令将补丁导入手机中

adb pushpatch_signed_7zip.apk文件路径  /storage/sdcard0/(手机存放的路径)

再用上面的加载补丁api即可

8.总结Tinker支持的功能

《热修复学习(3):Tinker组件依赖》 图片.png

热修复学习(1):Sophix
热修复学习(2):TinkerSDK

    原文作者:tmyzh
    原文地址: https://www.jianshu.com/p/35b69da294b5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞