Android热更新Tinker接入项目详解:
1 项目根目录build.gradle文件添加:
dependencies
{
classpath
'com.android.tools.build:gradle:3.4.1'
classpath
"com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.14"
}
2 APP的build.gradle文件中添加:
dependencies
{
annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:1.9.14")
implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.14")
}
头部添加
apply from
: 'tinkerpatch.gradle'
3 添加tinkerpatch.gradle文件
tinkerpatch.gradle文件内容如下:
apply plugin
: 'tinkerpatch-support'
def bakPath
= file("${buildDir}/bakApk/")
def baseInfo
= "tinkerapp-1.0.0-1031-17-05-07"
def variantName
= "release"
tinkerpatchSupport
{
tinkerEnable
= true
reflectApplication
= true
protectedApp
= false
supportComponent
= true
autoBackupApkPath
= "${bakPath}"
appKey
= "f589fed933b9ae15"
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"
}
android
{
defaultConfig
{
buildConfigField
"boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
}
}
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"
}
buildConfig
{
keepDexApply
= false
}
}
需要注意 def baseInfo = “tinkerapp-1.0.0-1031-17-05-07” tinkerEnable = true reflectApplication = true 这三个参数的意义
参数的详解查看 http://tinkerpatch.com/Docs/SDK
4 将SampleApplication接入到项目中
SampleApplication 代码如下:
package com
.test
.tinkerapp
;
import android
.app
.Application
;
import android
.content
.Context
;
import android
.support
.multidex
.MultiDex
;
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 java
.util
.HashMap
;
public class SampleApplication extends Application {
private static final String TAG
= "Tinker.SampleApppatch";
private ApplicationLike tinkerApplicationLike
;
public SampleApplication() {
}
@Override
public void attachBaseContext(Context base
) {
super.attachBaseContext(base
);
MultiDex
.install(base
);
}
@Override
public void onCreate() {
super.onCreate();
initTinkerPatch();
}
private void initTinkerPatch() {
if (BuildConfig
.TINKER_ENABLE
) {
tinkerApplicationLike
= TinkerPatchApplicationLike
.getTinkerPatchApplicationLike();
TinkerPatch
.init(
tinkerApplicationLike
)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(3)
;
Log
.d(TAG
, "Current patch version is " + TinkerPatch
.with().getPatchVersion());
TinkerPatch
.with().fetchPatchUpdateAndPollWithInterval();
}
}
private void useSample() {
TinkerPatch
.init(tinkerApplicationLike
)
.reflectPatchLibrary()
.fetchPatchUpdate(false)
.setFetchPatchIntervalByHours(3)
.fetchDynamicConfig(new ConfigRequestCallback() {
@Override
public void onSuccess(HashMap
<String, String> hashMap
) {
}
@Override
public void onFail(Exception e
) {
}
}, false)
.setFetchDynamicConfigIntervalByHours(3)
.setAppChannel("default")
.addIgnoreAppChannel("googleplay")
.setPatchCondition("test", "1")
.setPatchRestartOnSrceenOff(true)
.setPatchResultCallback(new ResultCallBack() {
@Override
public void onPatchResult(PatchResult patchResult
) {
Log
.i(TAG
, "onPatchResult callback here");
}
})
.setPatchRollbackOnScreenOff(true)
.setPatchRollBackCallback(new RollbackCallBack() {
@Override
public void onPatchRollback() {
Log
.i(TAG
, "onPatchRollback callback here");
}
});
}
private void complexSample() {
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());
TinkerPatch
.init(builder
.build());
}
}
5 在Tinker Platform 平台注册账号
地址:http://tinkerpatch.com/
直接都是下一步,最后拿到appKey,填入到tinkerpatch.gradle文件中的 appKey = “e9c7e10e43fe406f” 点击添加app版本,App版本号是项目中的 versionName “1.0.0”,如果这里填写的是versionName的值那么tinkerpatch.gradle文件中的 appVersion = “1.0.0”,这俩者是对应的;切记
6 生成Signing Configs(如果项目中已经有,可以忽略)
File>Project Structure
生成自己的Key store
Build>Generate Signed Bundle / APK…
以上准备工作已经完成
===============================================================
以下步骤是怎么生成补丁包
1 生成自己的release包
举个例子: MainActivity中有bug的内容(线上的包)
双击assembleRelease生成release包 同时在bakApk目录下会生成一个release包
修改bug:
当bug修改过后,在tinkerpatch.gradle文件的def baseInfo = “tinkerapp-1.0.0-1031-17-06-33”,把baseInfo 的值改为上一次的地址
双击tinkerPatchRelease生成补丁包:
当前的文件就是生成的补丁包
将生成的补丁包发到Tinker Platform平台上,点击提交就可以了
在模拟器中点击按钮,就可以强制更新平台上的包了,但是要想看到修改后的内容,必须把app kill掉,重新进去就可以看到了。
完毕
参考文档:http://tinkerpatch.com/