Tinker 入门
2020-03-06 本文已影响0人
细雨么么
1.集成
官方文档:http://tinkerpatch.com/Docs/SDK
app buildgragle 如下
apply plugin: 'com.android.application'
apply from : 'tinkerpatch.gradle'
android {
signingConfigs {
release {
storeFile file('D:\\s.jks')
storePassword 'android'
keyAlias = 'key0'
keyPassword 'android'
}
debug {
storeFile file('D:\\s.jks')
storePassword 'android'
keyAlias = 'key0'
keyPassword 'android'
}
}
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "com.vortex.rxtest"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "3.0.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
packagingOptions {
exclude 'META-INF/rxjava.properties'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
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:26.+'
compile 'com.android.support:design:26.+'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
compile 'io.reactivex.rxjava2:rxjava:2.2.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.2'
compile 'com.google.code.gson:gson:2.8.4'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
//转换结果Gson
compile 'com.squareup.retrofit2:converter-scalars:2.0.0'
//转换结果String
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
//妈的这里有个坑 rxjava2 不是rxjava:2.xxxx
testCompile 'junit:junit:4.12'
implementation files('libs/android.jar')
implementation files('libs/classes.jar')
compile("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.14.5")
}
1583473910(1).jpg
当然还有最上面的引用 ** apply from : 'tinkerpatch.gradle' **
tinkerpatch.gradle 如下
apply plugin: 'tinkerpatch-support'
import java.util.regex.Matcher
import java.util.regex.Pattern
/**
* TODO: 请按自己的需求修改为适应自己工程的参数
* 基包路径
* 基包文件夹名字
* 具体文件夹名
*/
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-3.0.1-0306-13-36-10"
def variantName = "release"
/**
* 对于插件各参数的详细解析请参考
* http://tinkerpatch.com/Docs/SDK
*/
tinkerpatchSupport {
/** 可以在debug的时候关闭 tinkerPatch, isRelease() 可以判断BuildType是否为Release **/
tinkerEnable = true
/**
* 是否反射 Application 实现一键接入;一般来说,
* 接入 Tinker 我们需要改造我们的 Application, 若这里为 true,
* 即我们无需对应用做任何改造即可接入。
*/
reflectApplication = true
/**
* 是否开启加固模式,只能在APK将要进行加固时使用,否则会patch失败。
* 如果只在某个渠道使用了加固,可使用多flavors配置
**/
protectedApp = false
/**
* 实验功能
* 补丁是否支持新增 Activity (新增Activity的exported属性必须为false)
**/
supportComponent = true
autoBackupApkPath = "${bakPath}"
appKey = "276d05f5af92cbe0"
/** 注意: 若发布新的全量包, appVersion一定要更新 **/
appVersion = "3.0.1"
def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
def name = "${project.name}-${variantName}"
baseApkFile = "${pathPrefix}/${name}.apk"
baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
baseResourceRFile = "${pathPrefix}/${name}-R.txt"
/**
* (可选)重命名备份文件的格式化字符串,默认为'${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}'
/**
* 若有编译多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
}
}
/**
* 如果只想在Release中打开tinker,可以把tinkerEnable赋值为这个函数的return
* @return 是否为release
*/
def isRelease() {
Gradle gradle = getGradle()
String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern;
if (tskReqStr.contains("assemble")) {
println tskReqStr
pattern = Pattern.compile("assemble(\\w*)(Release|Debug)")
} else {
pattern = Pattern.compile("generate(\\w*)(Release|Debug)")
}
Matcher matcher = pattern.matcher(tskReqStr)
if (matcher.find()) {
String task = matcher.group(0).toLowerCase()
println("[BuildType] Current task: " + task)
return task.contains("release")
} else {
println "[BuildType] NO MATCH FOUND"
return true;
}
}
image.png
image.png
image.png
image.png
package com.vortex.snaptest;
import android.app.Application;
import android.util.Log;
import com.tencent.tinker.entry.ApplicationLike;
import com.tencent.tinker.lib.listener.DefaultPatchListener;
import com.tencent.tinker.lib.patch.UpgradePatch;
import com.tencent.tinker.lib.reporter.DefaultLoadReporter;
import com.tencent.tinker.lib.reporter.DefaultPatchReporter;
import com.tencent.tinker.lib.service.PatchResult;
import com.tinkerpatch.sdk.TinkerPatch;
import com.tinkerpatch.sdk.loader.TinkerPatchApplicationLike;
import com.tinkerpatch.sdk.server.callback.ConfigRequestCallback;
import com.tinkerpatch.sdk.server.callback.RollbackCallBack;
import com.tinkerpatch.sdk.server.callback.TinkerPatchRequestCallback;
import com.tinkerpatch.sdk.tinker.callback.ResultCallBack;
import com.tinkerpatch.sdk.tinker.service.TinkerServerResultService;
import com.vortex.rxtest.BuildConfig;
import java.util.HashMap;
/**
* Created by Administrator (chenPS) on 2020/3/6.
*/
public class Mapplication extends Application {
private static final String TAG = "Tinker.SampleApppatch";
private ApplicationLike tinkerApplicationLike;
@Override
public void onCreate() {
super.onCreate();
initTinkerPatch();
}
/**
* 我们需要确保至少对主进程跟patch进程初始化 TinkerPatch
*/
private void initTinkerPatch() {
// 我们可以从这里获得Tinker加载过程的信息
if (BuildConfig.TINKER_ENABLE) {
tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK
TinkerPatch.init(
tinkerApplicationLike
// new TinkerPatch.Builder(tinkerApplicationLike)
// .requestLoader(new OkHttp3Loader())
// .build()
)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.fetchPatchUpdate(true)
.setFetchPatchIntervalByHours(3)
;
// 获取当前的补丁版本
Log.d(TAG, "Current patch version is " + TinkerPatch.with().getPatchVersion());
// fetchPatchUpdateAndPollWithInterval 与 fetchPatchUpdate(false)
// 不同的是,会通过handler的方式去轮询
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
}
}
/**
* 在这里给出TinkerPatch的所有接口解释
* 更详细的解释请参考:http://tinkerpatch.com/Docs/api
*/
private void useSample() {
TinkerPatch.init(tinkerApplicationLike)
//是否自动反射Library路径,无须手动加载补丁中的So文件
//注意,调用在反射接口之后才能生效,你也可以使用Tinker的方式加载Library
.reflectPatchLibrary()
//向后台获取是否有补丁包更新,默认的访问间隔为3个小时
//若参数为true,即每次调用都会真正的访问后台配置
.fetchPatchUpdate(false)
//设置访问后台补丁包更新配置的时间间隔,默认为3个小时
.setFetchPatchIntervalByHours(3)
//向后台获得动态配置,默认的访问间隔为3个小时
//若参数为true,即每次调用都会真正的访问后台配置
.fetchDynamicConfig(new ConfigRequestCallback() {
@Override
public void onSuccess(HashMap<String, String> hashMap) {
}
@Override
public void onFail(Exception e) {
}
}, false)
//设置访问后台动态配置的时间间隔,默认为3个小时
.setFetchDynamicConfigIntervalByHours(3)
//设置当前渠道号,对于某些渠道我们可能会想屏蔽补丁功能
//设置渠道后,我们就可以使用后台的条件控制渠道更新
.setAppChannel("default")
//屏蔽部分渠道的补丁功能
.addIgnoreAppChannel("googleplay")
//设置tinkerpatch平台的条件下发参数
.setPatchCondition("test", "1")
//设置补丁合成成功后,锁屏重启程序
//默认是等应用自然重启
.setPatchRestartOnSrceenOff(true)
//我们可以通过ResultCallBack设置对合成后的回调
//例如弹框什么
//注意,setPatchResultCallback 的回调是运行在 intentService 的线程中
.setPatchResultCallback(new ResultCallBack() {
@Override
public void onPatchResult(PatchResult patchResult) {
Log.i(TAG, "onPatchResult callback here");
}
})
//设置收到后台回退要求时,锁屏清除补丁
//默认是等主进程重启时自动清除
.setPatchRollbackOnScreenOff(true)
//我们可以通过RollbackCallBack设置对回退时的回调
.setPatchRollBackCallback(new RollbackCallBack() {
@Override
public void onPatchRollback() {
Log.i(TAG, "onPatchRollback callback here");
}
});
}
/**
* 自定义Tinker类的高级用法, 使用更灵活,但是需要对tinker有更进一步的了解
* 更详细的解释请参考:http://tinkerpatch.com/Docs/api
*/
private void complexSample() {
//修改tinker的构造函数,自定义类
TinkerPatch.Builder builder = new TinkerPatch.Builder(tinkerApplicationLike)
.listener(new DefaultPatchListener(this))
.loadReporter(new DefaultLoadReporter(this))
.patchReporter(new DefaultPatchReporter(this))
.resultServiceClass(TinkerServerResultService.class)
.upgradePatch(new UpgradePatch())
.patchRequestCallback(new TinkerPatchRequestCallback());
//.requestLoader(new OkHttpLoader());
TinkerPatch.init(builder.build());
}
}