添加project依赖:打开项目project的gradle添加以下代码
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
// TinkerPatch 插件,添加以下两行代码就行
classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.9"
classpath "com.tencent.bugly:tinker-support:1.1.5"
}
}
添加model依赖:打开model的gradle文件,如下添加依赖,只需要添加注释标明部分即可,这里我是固定使用的1.9.8的tinker
apply plugin: 'com.android.application'
apply from: 'tinkerpatch.gradle'//这里是需要添加的,这里是关联到tinkerpatch.gradle文件,这样我们就可以单独在tinkerpatch.gradle配置一切tinker的内容
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.yunmayi.cashier"
minSdkVersion 19
targetSdkVersion 26
versionCode 891
versionName "1.8.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
}
buildTypes {
release {
minifyEnabled false
multiDexKeepFile file('multidex-android.txt')
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
dexOptions {
jumboMode true
}
lintOptions {
abortOnError false
}
}
repositories {
maven {
url "http://dl.bintray.com/jlmd/maven"
}
}
dependencies {
//这里也是需要添加的,这是热修复依赖
annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:1.9.8")
compileOnly 'com.tinkerpatch.tinker:tinker-android-anno:1.9.8'
implementation 'com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.8'
}
添加tinkerPatch.gradle:这个步骤就是创建上面gradle依赖的tinkerpatch.gradle文件
第一步:新建一个gradle文件,名字叫做tinkerpatch.gradle,创建完成之后就是这样子了
第二步写入tinker配置。这里直接照抄官方的配置就可以,下面是我自己修改过的,下面图片是我自己的配置
apply plugin: 'tinkerpatch-support'
def bakPath = file("${buildDir}/bakApk/")//这个是编译基础包的位置
tinkerpatchSupport {
/** 编译时是否打开tinker(打开的话会在你的build/bakapk中多生成一个apk,同时编译速度加长)**/
tinkerEnable = true
/** 是否使用一键接入功能 **/
reflectApplication = true
/** 如果用了360加固或者其他之类的加固软件这个得打开,需要查看tinker官网是否支持你选用的加固工具 **/
protectedApp = false
/** 补丁是否支持新增 Activity (exported必须为false)**/
supportComponent = false
autoBackupApkPath = "${bakPath}"
/** 在tinkerpatch.com得到的appKey **/
appKey = "应用的appkey"
/** 注意: 若发布新的全量包, appVersion一定要更新 **/
appVersion = "891"//这个对应的是平台的补丁版本,是指的新建补丁那个版本,建议和应用版本号同步
/**bakapk目录下的apk文件
* 所谓基础包,是你在生成补丁包时,那个拿来对比的安装包,务必在出版本的时候保留,
**/
baseApkFile = "放置基础包的路径"
/**bakapk目录下的-mapping.txt文件
* 当你的应用开启混淆时会在bakapk和apk同一个目录下会生成这个文件,不开启混淆则不会生成
**/
baseProguardMappingFile = "放置混淆记录文件的路径"
/**bakapk目录下的-R.txt文件
* 在bakapk和apk同一个目录下会生成这个文件
**/
baseResourceRFile = "资源映射文件"
}
/**
* 用于用户在代码中判断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
}
}
再贴出一下bakapk的目录结构
直接在application中的onCreate中执行以下方法
private void initTinker() {
/*
* 我们需要确保至少对主进程跟patch进程初始化 TinkerPatch
*/
if (BuildConfig.TINKER_ENABLE) {
// 初始化TinkerPatch SDK, 更多配置可参照API章节中的,初始化SDK
TinkerPatch.init(mApplicationLike)
.setPatchResultCallback(new ResultCallBack() {
@Override
public void onPatchResult(PatchResult patchResult) {
Log.i("patch",patchResult.patchVersion);
}
})
.reflectPatchLibrary()
.fetchPatchUpdate(true)
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true);
// 每隔3个小时去访问后台时候有更新,通过handler实现轮训的效果
new FetchPatchHandler().fetchPatchWithInterval(3);
}
}
FetchPatchHandler的代码,主要就是一个定时器:
public class FetchPatchHandler extends Handler {
public static final long HOUR_INTERVAL = 3600 * 1000;
private long checkInterval;
/**
* 通过handler, 达到按照时间间隔轮训的效果
*/
public void fetchPatchWithInterval(int hour) {
//设置TinkerPatch的时间间隔
TinkerPatch.with().setFetchPatchIntervalByHours(hour);
checkInterval = hour * HOUR_INTERVAL;
//立刻尝试去访问,检查是否有更新
sendEmptyMessage(0);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里使用false即可
TinkerPatch.with().fetchPatchUpdate(false);
//每隔一段时间都去访问后台, 增加10分钟的buffer时间
sendEmptyMessageDelayed(0, checkInterval + 10 * 60 * 1000);
}
}
这样子,项目就配置好了tinker了,接下来是补丁生成和下发的部分。
生成基础文件:
这个步骤一般在实际项目中发生在出版本的时候,操作如下
执行完成之后会在bakapk目录下生成一个新的文件夹,里面包含了三个或者两个文件,把这几个文件放置到你tinkerpatch.gradle中配置的那个文件目录下方,这个apk就是提供给用户的apk
对比生成补丁,当我们发生bug之后,代码修改后,此时需要生成补丁上去修复故障,在生成基础文件的时候我们已经将基础文件放置到对应目录下了,那么接下来直接这么操作:
在编译完成之后会打印出如下日志
find the output 后面那个就是补丁包的生成路径了,路径下存在打好的补丁包了
这时候打开tinker官网找到自己需要发布的应用,创建好对应版本,然后选择文件下发就可以了,这个版本是和tinkerPatch.gradle里面配置的版本对应的。
1.tinker上传补丁包显示非法
这个问题首先检查你的补丁包大小是否正确,如果正确把电脑时间同步一下,然后重新构建补丁包,如果还有问题联系tinker工作人员处理一下(或者升级付费版,腾讯你懂得),上次我也是碰到这个问题没理他,过几天就能够正常上传了。
2.tinker修复之后程序直接崩溃
这边列举一种我碰到的错误:在补丁下发并且合成之后,再次打开程序,直接崩溃,显示资源未找到异常,这时候请检查你的补丁包文件夹是否有除了.apk之外的其他文件,如果有恭喜,这个文件通过充钱可以解决,首先说下产生原因:
tinker在生成补丁的时候会把设置的部分进行一个对比,一旦发生改变就会添加到补丁包中,这个是可以配置的,例如你的资源文件发生了改变,那么会多出一个resource.7z的资源补丁包,这时候在补丁包中指定的资源id就变了,就是R.id.xxx对应的那些R文件的资源变了,这时候你需要上传两个补丁一个是资源补丁,一个是代码补丁,不然会NotFoundException,在AS3.0开启了aapt2之后,莫名的所有资源都会检测到修改,这个我也不知道为啥,所以会生成一个巨大的资源补丁包,这时候官方免费的版本是不能上传太大文件的(所以如果想修改资源,建议使用付费版)。
重点来了:但是实际中如果你不需要替换资源,又想不交钱,那么可以指定对比的资源,只修改代码这时候也是能够解决问题的
配置tinkerPatch.gradle如下:
/**
* 一般来说,我们无需对下面的参数做任何的修改
* 对于各参数的详细介绍请参考:
* 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"]
}
//修改此处,这边是修改tinker打包资源时对比的资源选项,其中src是默认的,但是资源文件可以按照需
//要自己配置,我这边配置只对比AndroidMefest.xml的内容,所以我配置的tinker只能修改代码,这里按//照自己需要配置
res {
pattern = ["AndroidManifest.xml"]
ignoreChange = ["res/*","r/*", "assets/*", "resources.arsc",]
largeModSize = 100
}
packageConfig {
}
sevenZip {
zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
// path = "/usr/local/bin/7za"
}
buildConfig {
keepDexApply = false
}
}
其次在安卓8.0之后3小时一次的轮询据说失效,我没测试过,大家可以试试,且又听说在最新版本的tinker中添加了定时轮询,没去了解,小伙伴们可以自己试试。
撒有啦啦!!!