android robust加固,Android架构之路--热更新Tinker(上)

一、简介

当前市面的热补丁方案有很多,其中比较出名的有阿里的 AndFix、美团的 Robust 以及 QZone 的超级补丁方案。但它们都存在无法解决的问题,这也是正是最后使用 Tinker 的原因。先看一张图对比:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1-1:热更新对比图

Tinker热补丁方案不仅支持类、So 以及资源的替换,它还是2.X-7.X的全平台支持。利用Tinker我们不仅可以用做 bugfix,甚至可以替代功能的发布。Tinker已运行在微信的数亿Android设备上。

TinkerPatch 平台在 Github 为大家提供了各种各样的 Sample,大家可点击前往 [TinkerPatch Github].

Tinker原理图

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1-2:原理图

Tinker流程图

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1-3:Tinker 流程图

二、Tinker相关网站

微信Tinker Patch官网:Tinker Patch

Github地址:tinker

三、接入Tinker步骤

基础步骤

注册Tinker账户、添加APP、记录AppKey,添加 APP 版本、 发布补丁。详细步骤请移步Tinker平台使用文档

主要来说下配置Gradle和代码

1. 配置Tinker版本信息

我们使用配置文件去配置Tinker版本信息,易于统一版本和后面更换版本,如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-1 gradle.properties文件

代码如下:

TINKER_VERSION=1.9.6

TINKERPATCH_VERSION=1.2.6

2. 使用Tinker插件

在根目录下的build.gradle文件下配置,如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-2 添加Tinker插件

代码如下:

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

3. 配置Tinker的gradle脚本

在项目app目录下新建tinkerparch.gradle文件,如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-3 tinkerpatch.gradle

代码如下:

apply plugin: 'tinkerpatch-support'

/**

* TODO: 请按自己的需求修改为适应自己工程的参数

*/

def bakPath = file("${buildDir}/bakApk/")

def baseInfo = "app-1.0.0-0529-14-38-02"

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}"

/** 注意:换成自己在Tinker平台上申请的appKey**/

appKey = "521db2518e0ca16d"

/** 注意: 若发布新的全量包, 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:换成自己在Tinker平台上申请的。

baseInfo:基准包名称,使用Tinker脚本编译在模块的build/bakApk生成编译副本。

variantName: 这个一般对应buildTypes里面你基准包生成的类型,release、debug或其他

appVersion:配置和Tinker后台新建补丁包的一致。

其他地方可以暂时不用改

4. 配置模块下的build.gradle

配置签名

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-4:配置签名

在配置混淆代码的时候,想要提醒下大家,当设置 minifyEnabled 为false时代表不混淆代码,shrinkResources也应设置为false ,它们通常是彼此关联。

要是你设置minifyEnabled 为false,shrinkResources为true,将会报异常,信息如下:

Error:A problem was found with the configuration of task':watch:packageOfficialDebug'.

File '...\build\intermediates\res\resources-official-debug-stripped.ap_' specified for property 'resourceFile' does not exist.

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-4-1:混淆配置

配置依赖

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-5:配置Tinker依赖

使用插件

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-6:使用Tinker插件

具体代码如下:

apply plugin: 'com.android.application'

apply from: 'tinkerpatch.gradle'

android {

compileSdkVersion 25

buildToolsVersion "25.0.3"

defaultConfig {

applicationId "qqt.com.tinkerdemo"

minSdkVersion 17

targetSdkVersion 25

versionCode 1

versionName "1.0.0"

multiDexEnabled true

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

signingConfigs {

release {

storeFile file("./jks/tinker.jks")

storePassword "123456"

keyAlias "tinker"

keyPassword "123456"

}

debug {

storeFile file("./jks/debug.keystore")

}

}

buildTypes {

release {

minifyEnabled false

signingConfig signingConfigs.release

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

debug {

signingConfig signingConfigs.debug

}

}

}

dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {

exclude group: 'com.android.support', module: 'support-annotations'

})

compile 'com.android.support:appcompat-v7:25.3.1'

compile 'com.android.support.constraint:constraint-layout:1.0.2'

testCompile 'junit:junit:4.12'

annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {

changing = true

}

provided("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {

changing = true

}

compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") {

changing = true

}

compile 'com.android.support:multidex:1.0.1'

}

5. 代码集成

最后一步,在自己的代码新建一个Application,把代码集成在App中,别忘了在AndroidManifest里面配置APP。。。

如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2-7:集成代码

我是继承MultiDexApplication主要是防止64k异常。有关这块知识,请看Android 方法数超过64k、编译OOM、编译过慢解决方案

具体代码如下:

package qqt.com.tinkerdemo;

import android.support.multidex.MultiDexApplication;

import com.tencent.tinker.loader.app.ApplicationLike;

import com.tinkerpatch.sdk.TinkerPatch;

import com.tinkerpatch.sdk.loader.TinkerPatchApplicationLike;

/**

* 邮箱:ljh12520jy@163.com

*

* @author Ljh on 2018/5/28

*/

public class App extends MultiDexApplication {

private ApplicationLike mApplicationLike;

@Override

public void onCreate() {

super.onCreate();

mApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK

TinkerPatch.init(mApplicationLike)

.reflectPatchLibrary()

.fetchPatchUpdate(true)

// 强制更新

.setPatchRollbackOnScreenOff(true)

.setPatchRestartOnSrceenOff(true)

.setFetchPatchIntervalByHours(3);

// 每隔3个小时(通过setFetchPatchIntervalByHours设置)去访问后台时候有更新,

//通过handler实现轮训的效果

TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();

}

}

四、生成基准包

在生成基准包的时候,要注意一个问题,就是关闭 instant run(当tinkerEnable = true时,false的时候,就不需要),如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-1:关闭InstantRun

在Android Studio的右上角,点击Gradle,如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-2:准备生成基准包

双击assembleRelease生成成功后安装模块/build/outputs/apk/release/app-release.apk就OK了,这时候进去模块/build/bakApk里面记录一下类似app-1.0.0-0530-18-01-59的文件名称,只生成一次基准包,那么就会生成一个。这里需要注意一下,如果点太多生成太多的话确定不了刚刚生成的是哪个,那么就选最新那个或者删掉重新生成基准包。

生成后的基准包如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-3:生成基准包

五、修改bug

在自己的代码中随便修改点代码(Tinker1.9.6 里面支持新增Activity代码)

六、生成补丁包

在生成补丁包前,我们需要去tinkerpatch.gradle文件下修改一些信息。

baseInfo :把前面app-1.0.0-0529-14-38-02换成我们刚生成记录下的基准包(app-1.0.0-0530-18-01-59)就可以。

variantName : 因为刚刚我们使用assembleRelease生成的补丁,所以我们只需要使用release

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

生成的补丁包如图:

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-4:生成补丁包

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-5:tinkerPatch下的一些文件说明

七、发布补丁包

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

APP开启强制更新的话那么重启应用就会更新,否则会通过轮询去更新。应用重启才生效。

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-6:发布补丁包

注:在Tinker后台发布的差分包(补丁包)是根据app-1.0.0-0530-18-01-59为基准包下,修复bug生成的补丁包,只对于app-1.0.0-0530-18-01-59版本的apk生效。

b6374b15c0d4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

3-7:差分包

看到这里已经我们已经集成Tinker热更新成功,下篇将讲解基于Tinker实现多渠道打包发布Android架构之路--热更新Tinker(下)

参考文章

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值