【Android】热修复之Tinker的集成与使用

【Android】热修复之Tinker的集成与使用_第1张图片

前言

近年来随着Android用户的爆发式增长,Android应用也逐渐完善,应用再也不是只需要会四大组件就可以满足产品的需求,出现了很多三方的SDK,优秀的类库,还有个性化的插件。热修复在近年来特别hot,下面我们就来介绍一下业界评价最好的热修复之一Tinker!

我们先来比较一下当下热修复界中的四大天王(分别来自微信,QQ空间,阿里,美团):
【Android】热修复之Tinker的集成与使用_第2张图片
什么是Tinker?

tinker是微信官方的Android热补丁解决方案,官方是这么概括Tinker的:Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk。用于给程序打补丁,不需要重新安装,支持动态下发代码、So库以及资源等
可以说很全面了,不管是Java类、xml布局文件、图片甚至是So库都可以用热修复来修改~
我们要介绍的是自定义Tinker的集成与使用,需要后台的支持,如果不想这么麻烦,可以尝试TinkerPatch的一键傻瓜式接入,具体的可参考文档TinkerPatch 平台介绍。
这款优秀的热修复的GitHub地址是:https://github.com/Tencent/tinker
官方文档:http://www.tinkerpatch.com/Docs/intro

怎样集成Tinker?(自定义Tinker )

1.设置tinker版本 :
在gradle.properties文件中 添加tinker版本号,方便以后升级时修改:

 TINKER_VERSION=1.9.1

2.在项目的build.gradle文件中添加依赖:

dependencies {
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // TinkerPatch 插件
         classpath'com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}’
    }
}

3.配置app的build.gradle文件
可以依照 tinker-sample-android 项目的build.gradle文件配置
https://github.com/Tencent/tinker/tree/master/tinker-sample-android
注:build.gradle配置文件中记得配置keysotre 密码,如果和debug模式,要将自己电脑的debug.keystore文件复制到app下keystore文件夹中

  • debug.keystore在自己电脑 C:\Users<用户名>.Android\debug.keystore

在运行demo时可能出现tinkerId未设置问题,这是由于demo中tinkerId为git的版本,当你本地无法获取git的版本时,会报错,
可以将thinkerId设置为应用的versionName,tinkerId保证其唯一性即可,每次升级app tinkerId也需要更新,继续与versionName保持一致。如下当前App的版本号是5.22:

def gitSha() {
    try {
//        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()
//        if (gitRev == null) {
//            throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
//        }
        //设置tinkerId,与versionName一致即可
        return '5.22'
//        return gitRev
    } catch (Exception e) {
        throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
    }
}

4.添加sd的读写权限

    
    
  1. 改造Application
    请参考SampleApplicationLike来看!
    将原来自定义的Application子类中的逻辑移动到
    SampleApplicationLike中
    【Android】热修复之Tinker的集成与使用_第3张图片
    【Android】热修复之Tinker的集成与使用_第4张图片

    修改Application,然后将Application类继承TinkerApplication.java。`除了构造方法之外,你最好不要引入其他的类,这将导致它们无法通过补丁修改。
public class SampleApplication extends TinkerApplication {
    public SampleApplication() {
      super(
        //tinkerFlags, tinker支持的类型,dex,library,还是全部都支持!
        ShareConstants.TINKER_ENABLE_ALL,
        //ApplicationLike的实现类,只能传递字符串 
        "tinker.sample.android.app.SampleApplicationLike",
        //Tinker的加载器,一般来说用默认的即可
        "com.tencent.tinker.loader.TinkerLoader",
        //tinkerLoadVerifyFlag, 运行加载时是否校验dex与,ib与res的Md5
        false);
    }  
}

具体的数值含义:
【Android】热修复之Tinker的集成与使用_第5张图片

为了隐藏你的Application类,我们更加推荐你使用tinker-android-anno在运行时生成你的Application类。这样保证你无法修改你的Application类,不会因为错误操作导致引入更多无法修改的类。

@DefaultLifeCycle(
application = ".SampleApplication",                       //application类名
flags = ShareConstants.TINKER_ENABLE_ALL,                 //tinkerFlags
loaderClass = "com.tencent.tinker.loader.TinkerLoader",   //loaderClassName, 我们这里使用默认即可!
loadVerifyFlag = false)                                   //tinkerLoadVerifyFlag
public class SampleApplicationLike extends DefaultApplicationLike

记得在清单文件中配置application名称:



一些自定义扩展类
这些类为我们提供了许多方法
比如加载补丁时的各种回调函数,详情见文档

我这里直接采用的demo中的类
【Android】热修复之Tinker的集成与使用_第6张图片

注意其中有个service,在补丁加载成功或失败时会执行 记得在清单文件中配置。
怎样使用Tinker?

如果按照demo中app的build.gradle文件配置,那么每次运行或者打包时均会在build/bakApk中生成apk、R.txt、 mapping文件
【Android】热修复之Tinker的集成与使用_第7张图片

每次正式发布版本后需要保存这个包的apk(基准包) R.txt(用于修改了资源文件时打补丁) mapping.txt(如果基准包进行了混淆,打补丁时需要用到)

制作补丁
1.修改代码、资源文件 解决bug修复

2.在app的build.gradle文件中填写基准包的信息 :
【Android】热修复之Tinker的集成与使用_第8张图片

3.运行 命令行: gradlew tinkerPatchRelease 或者 tinkerPatchDebug
【Android】热修复之Tinker的集成与使用_第9张图片

完毕后就得到了补丁包
【Android】热修复之Tinker的集成与使用_第10张图片

4.去自己的后台管理系统传补丁包并开启
【Android】热修复之Tinker的集成与使用_第11张图片
重启应用,使之生效。
加载补丁的api
TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");
加载补丁的结果

在tinker包下SampleResultService类中处理
多Flavor打包

有的时候我们希望通过flavor方式打包,在sample中提供了简单的用法事例:
1.通过flavor编译,这个时候我们可以看到bakApk路径是一个按照flavor名称区分的目录;
2.将编译目录路径填写到sample中tinkerBuildFlavorDirectory,其他的几个字段不需要填写,这里会自动根据路径拼接;

ext {
    tinkerBuildFlavorDirectory = "${bakPath}/app-1014-13-35-12"
}

3.运行tinkerPatchAllFlavorDebug或者tinkerPatchAllFlavorRelease即可得到所有flavor的补丁包。

  • 关于同一版本多次打补丁问题
    Tinker支持对同一基准版本做多次补丁修复,在生成补丁时,oldApk依然是已经发布出去的那个版本。即补丁版本二的oldApk不能是补丁版本一,它应该依然是用户手机上已经安装的基准版本。
    为避免重复下载补丁包,补丁包也应有‘版本号’
    调用接口获取此时客户端版本对应的补丁包信息:
    补丁包版本号 (每次在后台上传补丁包时版本号自动递增最佳)

你可能感兴趣的:(【Android】热修复之Tinker的集成与使用)