 
	                                            Tinker是微信官方的Android热补丁解决方案,支持动态下发代码、So 库以及资源,让应用能够在不需要重新安装的情况下实现更新。本文介绍下Android Studio如何通过TinkerPatch引入Tinker让你的Android应用支持热部署。
Android热部署
Android热部署,又称为热修复、热更新、动态加在等,简而言之就是不需要用户全量更新apk文件,而是只更新一小部分内容,可以在用户不察觉的情况下把这些小改动加进去,让bug修复和小功能添加变得异常简单。
Tinker介绍
Tinker 是一个开源项目(Github链接),它是微信官方的 Android 热补丁解决方案,它支持动态下发代码、So 库以及资源,让应用能够在不需要重新安装的情况下实现更新。
与市面上其他常见的热部署方案比较如下:
| 功能 | Tinker | QZone | AndFix | Robust | 
|---|---|---|---|---|
| 类替换 | yes | yes | no | no | 
| So替换 | yes | no | no | no | 
| 资源替换 | yes | yes | no | no | 
| 全平台支持 | yes | yes | no | yes | 
| 即时生效 | no | no | yes | yes | 
| 性能损耗 | 较小 | 较大 | 较小 | 较小 | 
| 补丁包大小 | 较小 | 较大 | 一般 | 一般 | 
| 开发透明 | yes | yes | no | no | 
| 复杂度 | 较低 | 较低 | 复杂 | 复杂 | 
| Rom体积 | Dalvik较大 | 较小 | 较小 | 较小 | 
| 成功率 | 较高 | 较高 | 一般 | 最高 | 
Tinker热补丁方案不仅支持类、So 以及资源的替换,它还是2.X-7.X的全平台支持。利用Tinker我们不仅可以用做 bug fix,甚至可以替代功能的发布。
TinkerPatch
Tinker 需要使用者有一个后台可以下发和管理补丁包,并且需要处理传输安全等部署工作,TinkerPatch 平台帮你做了这些工作,提供了补丁后台托管,版本管理,保证传输安全等功能,让你无需搭建一个后台,无需关心部署操作,只需引入一个 SDK 即可立即使用 Tinker。
此外,通过深入研究 Tinker 源码,TinkerTinkerPatch 平台在 Tinker的基础上加入了以下特性:
- 一键傻瓜式接入;无需理解复杂的热修复原理,一行代码即可接入热修复。实现了自动反射 Appliction 与 Library,使用者无需对自己的项目做任何的改动;
- 补丁管理;实现了热补丁的版本管理,补丁的自动重试与异常时自动回退等功能。同时我们可以简单实现条件下发补丁,在出现异常情况时,我们也可以快速回滚补丁;
- 编译优化;简化了 Tinker 的编译复杂度,实现了备份路径选择,功能开关等功能。
配置TinkerPatch
下面介绍下如何在Android Studio中配置TinkerPatch。
1.添加gradle插件依赖
在工程的build.gradle文件添加如下依赖(classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.11"):
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.11"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
2.添加TinkerPach SDK依赖
在app(主项目)的build.gradle里添加如下依赖:
dependencies {
    ...
    // 若使用annotation需要单独引用,对于tinker的其他库都无需再引用
    compileOnly("com.tinkerpatch.tinker:tinker-android-anno:1.9.11")
    implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.11")
}
3.TinkerPach配置文件
新建一个配置文件tinkerpath.gradle(与app的build.gradle同级),内容如下,这里需要注意的几个参数包括baseInfo,appVersion和appKey:
apply plugin: 'tinkerpatch-support'
/**
 * TODO: 请按自己的需求修改为适应自己工程的参数
 */
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-1.0.0-0416-18-55-33"
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 = "your key"
    /** 注意: 若发布新的全量包, 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
    }
}
4.初始化TinkerPatch
在Application类里初始化TinkerPatch:
        ApplicationLike tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
        TinkerPatch.init(tinkerApplicationLike)
                .reflectPatchLibrary()
                .setPatchRestartOnSrceenOff(true)
                .setPatchRestartOnSrceenOff(true)
                .setFetchPatchIntervalByHours(3);
        TinkerPatch.with().fetchPatchUpdate(true);
使用TinkerPatch
我一般的使用步骤如下:
1.发布release版的APK
在app的build.gradle里修改如下:
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    signingConfigs {
        release {
            storeFile file('C:\\Users\\xxx\\xxx\\xxx.jks')  //路径
            storePassword 'xxx'
            keyAlias 'xxx'
            keyPassword 'xxx'
        }
    }
    defaultConfig {
        applicationId "com.xxx.xxx"
        minSdkVersion 15
        targetSdkVersion 28
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7
        }
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath true
            }
        }
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
    }
}
然后在Gradle Task里选择app -> Tasks -> build -> assembleRelease,发布release版本的apk。
2.生成Tinker Patch包
当你修改了什么小bug,需要发布一个版本,就直接app -> Tasks -> tinker-> tinkerPatchRelease,之后会在outputs里有一个patch_signed_7zip.apk,把这个上传到TinkerPatch网上就行了。
关于注册TInkerPatach账号可以参考:http://www.tinkerpatch.com/Docs/start
更多配置参考TinkerPatch官方文档:http://www.tinkerpatch.com/Docs/SDK
 
	                    						

相关文章