tinker-platform热更新及android studio配置

                                    tinker-platform使用简书

1.sdk下载。

 

2.第一步 添加 gradle 插件依赖

gradle 远程仓库依赖 jcenter, 例如 TinkerPatch Sample 中的 build.gradle.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // TinkerPatch 插件
        classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.9"
    }
}
注意,在这里 SDK 使用了 fat 打包的模式,我们不能再引入任何 Tinker 的相关依赖,否则会造成版本冲突。

3.集成 TinkerPatch SDK

添加 TinkerPatch SDK 库的 denpendencies 依赖, 可参考 Sample 中的 app/build.gradle:
dependencies {
    // 若使用annotation需要单独引用,对于tinker的其他库都无需再引用
    provided("com.tinkerpatch.tinker:tinker-android-anno:1.9.9")
    compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.9")
}
注意,若使用 annotation 自动生成 Application, 需要单独引入 Tinker 的 tinker-android-anno 库。除此之外,我们无需再单独引入 tinker 的其他库。
为了简单方便,我们将 TinkerPatch 相关的配置都放于 tinkerpatch.gradle 中, 我们需要将其引入:
apply from: 'tinkerpatch.gradle'

4.配置 tinkerpatchSupport 参数

打开引入的 tinkerpatch.gradle 文件,它的具体参数如下:
tinkerpatchSupport {
    /** 可以在debug的时候关闭 tinkerPatch **/
    tinkerEnable = true

    /** 是否使用一键接入功能  **/
    reflectApplication = true

    /** 是否开启加固模式,只有在使用加固时才能开启此开关 **/
    protectedApp = false

    /** 补丁是否支持新增 Activity (exported必须为false)**/
    supportComponent = false

    autoBackupApkPath = "${bakPath}"

    /** 在tinkerpatch.com得到的appKey **/
    appKey = "yourAppKey"
    /** 注意: 若发布新的全量包, 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"
}

参数说明:

参数

默认值

描述

tinkerEnable

true

是否开启 tinkerpatchSupport 插件功能。

appKey

""

在 TinkerPatch 平台 申请的 appkey, 例如 sample 中的 'f828475486f91936'

appVersion

""

在 TinkerPatch 平台 输入的版本号, 例如 sample 中的 '1.0.0'。 注意,我们使用 appVersion 作为 TinkerId, 我们需要保证每个发布出去的基础安装包的 appVersion 都不一样。

reflectApplication

false

是否反射 Application 实现一键接入;一般来说,接入 Tinker 我们需要改造我们的 Application, 若这里为 true, 即我们无需对应用做任何改造即可接入。

autoBackupApkPath

""

将每次编译产生的 apk/mapping.txt/R.txt 归档存储的位置

baseApkFile

""

基准包的文件路径, 对应 tinker 插件中的 oldApk 参数;编译补丁包时,必需指定基准版本的 apk,默认值为空,则表示不是进行补丁包的编译。

baseProguardMappingFile

""

基准包的 Proguard mapping.txt 文件路径, 对应 tinker 插件 applyMapping 参数;在编译新的 apk 时候,我们希望通过保持基准 apk 的 proguard 混淆方式,从而减少补丁包的大小。这是强烈推荐的,编译补丁包时,我们推荐输入基准 apk 生成的 mapping.txt 文件。

baseResourceRFile

""

基准包的资源 R.txt 文件路径, 对应 tinker 插件 applyResourceMapping 参数;在编译新的apk时候,我们希望通基准 apk 的 R.txt 文件来保持 Resource Id 的分配,这样不仅可以减少补丁包的大小,同时也避免由于 Resource Id 改变导致 remote view 异常。

protectedApp

false

是否开启支持加固,注意:只有在使用加固时才能开启此开关

supportComponent

false

是否开启支持在补丁包中动态增加Activity 注意:新增Activity的Exported属性必须为false

backupFileNameFormat

'${appName}-${variantName}'

格式化命名备份文件 这里请使用单引号

一般来说,我们无需修改引用 android 的编译配置,也不用修改 tinker 插件原来的配置。针对特殊需求,具体的参数含义可参考 Tinker 文档:Tinker 接入指南.

5.初始化 TinkerPatch SDK

最后在我们的代码中,只需简单的初始化 TinkerPatch 的 SDK 即可,我们无需考虑 Tinker 是如何下载/合成/应用补丁包, 也无需引入各种各样 Tinker 的相关类。
1. reflectApplication = true 的情况
若我们使用 reflectApplication 模式,我们无需为接入 Tinker 而改造我们的 Application 类。初始化 SDK 可参考 tinkerpatch-easy-sample 中的 SampleApplication 类.
public class SampleApplication extends Application {

    ...

    @Override
    public void onCreate() {
        super.onCreate();
        // 我们可以从这里获得Tinker加载过程的信息
        tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

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

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

    ...

我们将 Tinker 加载补丁过程的结果存放在 TinkerPatchApplicationLike 中。
2. reflectApplication = false 的情况
若我们已经完成了应用的 Application 改造,即将 Application 的逻辑移动到 ApplicationLike类中。我们可以参考 tinkerpatch-sample 中的 SampleApplicationLike 类.
public class SampleApplicationLike extends DefaultApplicationLike {

    ...

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化 SDK
        TinkerPatch.init(this)
            .reflectPatchLibrary()
            .setPatchRollbackOnScreenOff(true)
            .setPatchRestartOnSrceenOff(true)
            .setFetchPatchIntervalByHours(3);

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

    ...

}
注意:初始化的代码建议紧跟 super.onCreate(),并且所有进程都需要初始化,已达到所有进程都可以被 patch 的目的
如果你确定只想在主进程中初始化 tinkerPatch,那也请至少在 :patch 进程中初始化,否则会有造成 :patch 进程crash,无法使补丁生效

6.使用步骤

TinkerPatch 的使用步骤非常简单,一般来说可以参考以下几个步骤:

  1. 运行 assembleRelease task 构建基准包(请在发布前确保更新tinkerpatchSupport中的appVersion),tinkerPatch会基于你填入的autoBackupApkPath自动备份基础包信息到相应的文件夹,包含:apk文件、R.txt文件和mapping.txt文件 (注:mapping.txt是proguard的产物,如果你没有开启proguard则不会有这个文件)
  2. 若想发布补丁包, 只需将自动保存下来的文件分别填到tinkerpatchSupport中的baseApkFile、baseProguardMappingFile和baseResourceRFile 参数中;
  3. 运行 tinkerPatchRelease task 构建补丁包,补丁包将位于 build/outputs/tinkerPatch下。

其他

1. 对Flavors的支持

在TinkerPatchSupport中添加如下字段, 如果你只是多渠道的需求,建议不要使用Flavor。多flavor必须在后台建立相应的基线工程(如下例子的命名规则为:appVersion_flavorName),每次生成补丁时也必须对应的生成多个分别上传。

这里增加了tinkerPatchAllFlavorsDebug 和 tinkerPatchAllFlavorsRelease 用于一次性生成所有flavors的Patch包。

具体可以参照tinkerpatch-flavors-sample

如果只是多渠道的需求,建议不要使用flavor的方式。首先其打包很慢,其次需要维护多个基线包,后期维护成本也很大。Tinker官方推荐 [packer-ng-plugin](https://github.com/mcxiaoke/packer-ng-plugin )或者 walle 来进行多渠道打包,其中walle是支持最新的SchemaV2签名的。

/** 若有编译多flavors需求,可在flavors中覆盖以下参数 * 你也可以直接通过tinkerPatchAllFlavorDebug/tinkerPatchAllFlavorRelease, 一次编译所有的flavor补丁包 * 注意的是:除非你不同的flavor代码是不一样的,不然建议采用zip comment或者文件方式生成渠道信息 **/ productFlavors { flavor { flavorName = "flavor1" // 后台需要按照每个flavor的appVersion来建立独立的工程,并单独下发补丁 appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}" pathPrefix = "${bakPath}/${baseInfo}/${flavorName}${buildType}/" name = "${project.name}-${flavorName}${buildType}" baseApkFile = "${pathPrefix}/${name}.apk" baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt" baseResourceRFile = "${pathPrefix}/${name}-R.txt" } flavor { flavorName = "flavor2" // 后台需要按照每个flavor的appVersion来建立独立的工程,并单独下发补丁 appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}" pathPrefix = "${bakPath}/${baseInfo}/${flavorName}${buildType}/" name = "${project.name}-${flavorName}${buildType}" baseApkFile = "${pathPrefix}/${name}.apk" baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt" baseResourceRFile = "${pathPrefix}/${name}-R.txt" } }

2. 对加固的支持

这里默认大家有同时生成加固渠道与非加固渠道的需求,如果只是单一需要加固,可以直接在配置中开启protectedApp = true即可。

可以参考tinkerpatch.gradle文件,具体工程可以参照tinkerpatch-flavors-sample

productFlavors { flavor { flavorName = "protect" appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}" pathPrefix = "${bakPath}/${baseInfo}/${flavorName}-${variantName}/" name = "${project.name}-${flavorName}-${variantName}" baseApkFile = "${pathPrefix}/${name}.apk" baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt" baseResourceRFile = "${pathPrefix}/${name}-R.txt" /** 开启加固开关,上传此flavor的apk到加固网站进行加固 **/ protectedApp = true } flavor { flavorName = "flavor1" appVersion = "${tinkerpatchSupport.appVersion}_${flavorName}" pathPrefix = "${bakPath}/${baseInfo}/${flavorName}-${variantName}/" name = "${project.name}-${flavorName}-${variantName}" baseApkFile = "${pathPrefix}/${name}.apk" baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt" baseResourceRFile = "${pathPrefix}/${name}-R.txt" } }

加固步骤: 

  1. 生成开启protectedApp = true的基础包(这里假设此APK名为:protected.apk);
  2. 上传protected.apk到相应的加固网站进行加固,并发布应用市场(请遵循各个加固网站步骤,一般为下载加固包-》重新签名-》发布重签名加固包);
  3. 在tinkerPatch后台根据appVersion建立相应的App版本(比如这里2个flavor,就需要建立2个App版本。App版本即为各自flavor中配置的appVersion);
  4. 基于各个flavor的基础包(这里的基础包是第一步中生成的未加固的版本)生成相应patch包,并上传至相应的App版本中,即完成补丁发布。

protectedApp=true, 这种模式仅仅可以使用在加固应用中

支持列表: 

加固厂商

测试

乐加固

Tested

爱加密

Tested

梆梆加固

Tested

360加固

Tested

其他

请自行测试,只要满足下面规则的都可以支持

这里是否支持加固,需要加固厂商明确以下两点:

  1. 不能提前导入类;
  2. 在art平台若要编译oat文件,需要将内联取消。

3. 重命名备份文件

/** * (可选)重命名备份文件的格式化字符串,默认为'${appName}-${variantName}' * * Available vars: * 1. projectName * 2. appName * 3. packageName * 4. buildType * 5. versionName * 6. versionCode * 7. buildTime * 8. fileSHA1 * 9. flavorName * 10. variantName * * default value: '${appName}-${variantName}' * Note: plz use single-quotation wrapping this format string ** / backupFileNameFormat = '${appName}-${variantName}'

4. 对新增Activity的支持

基础包必须设置supportComponent=true,并且新增Activity的Exported属性必须为false。

二.项目的编译

1.先配置项目的singnConfig

2.再配置项目中release和debug的内容

3.进行打包

4.进行打差异包(补丁)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值