Android热更新利器Tinker接入

参考

腾讯Tinker官方文档

建议大家先使用demo实验,成功后再集成到真正项目中。。。因为。。。你懂的!!!

写在前面

好久没有写博客了,都用笔记的形式记录了所学的东西。最近面试跟面试官聊起,发现写博客真的是一个好习惯,希望坚持下去吧。本文的目的就一个,让应用接入Tinker热更新,我们不去探究这东西怎么实现,本文仅仅作为工具使用指南。
类似的原理性文章可以参考下拙作:
Android黑科技动态加载(一)之Java中的ClassLoader
Android黑科技动态加载(二)之Android中的ClassLoader
Android黑科技动态加载(三)之动态加载资源
Android黑科技动态加载(四)之插件化开发

基准包

例如有一个版本A,但是这时A是有Bug的,然后修复Bug后的生成的版本我们称为B。A和B之间的区别产生一个差分包(这里也称为补丁包),那么我们就可以说这个差分包是以A作为基准包相对B生成的。参考增量更新文章:Android NDK开发两部曲(二)之应用篇(增量更新也就那样)

基本步骤

1、注册Tinker账号并新建项目,传送门
2、配置gradle和代码
3、生成基准包
4、修复Bug
5、生成补丁包
6、发布补丁包

Tinker做了什么

1、1-2步是APP开发的基本步骤,完成1-3步,那么你的APP就集成了Tinker。
集成Tinker后,Tinker会根据各个版本的配置信息去自动加载补丁。可配置强制更新,也可配置轮询更新。

2、第3步则是保留一个之前版本副本,用于后面生成补丁。为什么要这样做?因为1.0.2的相对于1.0.1的补丁包只能作用在1.0.1版本上。如果想要处理1.0.0那么有两种方法,使用1.0.0->1.0.1和1.0.1->1.0.2两个补丁包。但是也可以生成1.0.0->1.0.2的补丁包。所以副本保留还是有必要的。
3、4-6部就是真正应用到生产环境上了,真正达到热修复的作用。

一、注册Tinker账号

这个就不说了,Tinker注册和新建项目都好简单,也没有什么需要注意的。拿到appKey

二、配置Gradle和代码

这个推荐我们的拷贝粘贴代码

1、配置Tinker版本信息

我们使用配置文件去配置版本信息,易于统一版本和后面更换版本
编辑根目录的gradle.properties,加入

TINKER_VERSION=1.9.2
TINKERPATCH_VERSION=1.2.2

2、配置根目录下的build.gradle文件

使用Tinker插件

classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:${TINKERPATCH_VERSION}"

3、配置Tinker的gradle脚本

在项目根目录新建tinkerpatch.gradle文件

apply plugin: 'tinkerpatch-support'

/**
 * TODO: 请按自己的需求修改为适应自己工程的参数
 */
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-1.0.0-1213-19-52-36"
def variantName = "release"

/**
 * 对于插件各参数的详细解析请参考
 * http://tinkerpatch.com/Docs/SDK
 */
tinkerpatchSupport {
    /** 可以在debug的时候关闭 tinkerPatch **/
    /** 当disable tinker的时候需要添加multiDexKeepProguard和proguardFiles,
        这些配置文件本身由tinkerPatch的插件自动添加,当你disable后需要手动添加
        你可以copy本示例中的proguardRules.pro和tinkerMultidexKeep.pro,
        需要你手动修改'tinker.sample.android.app'本示例的包名为你自己的包名, com.xxx前缀的包名不用修改
     **/
    tinkerEnable = true
    reflectApplication = true
    /**
     * 是否开启加固模式,只能在APK将要进行加固时使用,否则会patch失败。
     * 如果只在某个渠道使用了加固,可使用多flavors配置
     **/
    protectedApp = false
    /**
     * 实验功能
     * 补丁是否支持新增 Activity (新增Activity的exported属性必须为false)
     **/
    supportComponent = true

    autoBackupApkPath = "${bakPath}"

    appKey = "c6a00cf4aafa2ab2"

    /** 注意: 若发布新的全量包, appVersion一定要更新 **/
    appVersion = "1.0.0"

    def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
    def name = "${project.name}-${variantName}"

    baseApkFile = "${pathPrefix}/${name}.apk"
    baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
    baseResourceRFile = "${pathPrefix}/${name}-R.txt"

    /**
     *  若有编译多flavors需求, 可以参照: https://github.com/TinkerPatch/tinkerpatch-flavors-sample
     *  注意: 除非你不同的flavor代码是不一样的,不然建议采用zip comment或者文件方式生成渠道信息(相关工具:walle 或者 packer-ng)
     **/
}

/**
 * 用于用户在代码中判断tinkerPatch是否被使能
 */
android {
    defaultConfig {
        buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
    }
}

/**
 * 一般来说,我们无需对下面的参数做任何的修改
 * 对于各参数的详细介绍请参考:
 * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
 */
tinkerPatch {
    ignoreWarning = false
    useSign = true
    dex {
        dexMode = "jar"
        pattern = ["classes*.dex"]
        loader = []
    }
    lib {
        pattern = ["lib/*/*.so"]
    }

    res {
        pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
        ignoreChange = []
        largeModSize = 100
    }

    packageConfig {
    }
    sevenZip {
        zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
//        path = "/usr/local/bin/7za"
    }
    buildConfig {
        keepDexApply = false
    }
}

注意几个字段内容,主要是后面生成补丁需要用到的,除了AppKey外其他暂时不用改
baseInfo : 这个是基准包的名称,使用Tinker脚本编译在模块的build/bakApk生成编译副本
variantName : 这个一般对应buildTypes里面你基准包生成的类型,release、debug或其他
appKey : 这个就是Tinker新建项目时拿到的appKey
appVersion : 配置和Tinker后台新建补丁包的一致

4、配置模块下的buidle.gradle

A、配置应用签名

这个百度搜都有,大概就这样

    signingConfigs {
        release {//发布版本的签名配置
            storeFile file('key.jks')
            keyAlias 'test'
            storePassword '123456789'
            keyPassword '123456789'
        }
        debug {//调试版本的签名配置
            storeFile file('key.jks')
            keyAlias 'test'
            storePassword '123456789'
            keyPassword '123456789'
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }

B、配置依赖

 //若使用annotation需要单独引用,对于tinker的其他库都无需再引用
        annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
            changing = true
        }
        compileOnly("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
            changing = true
        }
        implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") {
            changing = true
        }

C、使用插件

在模块的build.gradle加入

apply from: 'tinkerpatch.gradle'

3、代码配置

最后一步配置,把代码集成到App里,别忘了在AndroidManifest里面配置APP。。。

public class App extends Application {
    private ApplicationLike tinkerApplicationLike;

    @Override
    public void onCreate() {
        super.onCreate();
        tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

        // 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
        TinkerPatch.init(tinkerApplicationLike)
                .reflectPatchLibrary()
                .fetchPatchUpdate(true)
        // 强制更新
                .setPatchRollbackOnScreenOff(true)
                .setPatchRestartOnSrceenOff(true)
                .setFetchPatchIntervalByHours(3);

        // 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,通过handler实现轮训的效果
        TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
    }
}

三、生成基准包

其实到了这里就配置完成了,我们生产一个基准包

《Android热更新利器Tinker接入》 生成基准包

双击assembleRelease生成成功后安装模块/build/outputs/apk/release/app-release.apk就OK了,这时候进去模块/build/bakApk里面记录一下类似app-1.0.0-1213-19-52-36的文件名称,只生成一次基准包,那么就会生成一个。但是如果手贱点太多生成太多的话确定不了刚刚生成的是哪个,那么就选最新那个或者删掉重新生成基准包,真实环境并不允许这样搞。。。

《Android热更新利器Tinker接入》 安装包
《Android热更新利器Tinker接入》 基准包名称

四、修复bug

随便修改点代码

五、生成补丁包

这时候我们就需要去修改一些tinkerpatch.gradle文件的信息了。
baseInfo :还记得app-1.0.0-1213-19-52-36这个东西吗?换成自己上面记录的就OK了
variantName : 因为刚刚我们使用assembleRelease生成的补丁,所以我们只需要使用release就OK了

《Android热更新利器Tinker接入》 生成差分包

双击TinkerPatchRelease生成差分包,patch_signed_7zip.apk就是补丁包了

《Android热更新利器Tinker接入》 补丁包

六、发布补丁包

回到Tinker后台,选中我们开始新建的项目,补丁下发->添加APP版本。然后上传刚刚的patch_signed_7zip.apk

《Android热更新利器Tinker接入》 发布补丁包

APP开启强制更新的话那么重启应用就会更新,否则会通过轮询去更新。应用重启才生效。Tinker太强大了,本文目的就是把项目跑通,相信后面的很多功能大家有兴趣的话一起发现,一起讨论。

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