Tinker熱修復框架接入
阿新 • • 發佈:2019-01-10
Tinker熱修復框架接入
Android現在開發App基本都開始接入熱修復框架,為的就是能夠修復一些線上緊急Bug。熱門的熱修復框架以及對比,網上介紹的也很多,個人而言就用過騰訊的tinker以及阿里的sophix。
騰訊tinkerTinker簡介,根據官方文件接入tinker,然後測試熱修復補丁,總是莫名地失敗(或許是自己技術太渣)。無奈就不去折騰它,而選擇了第三方的tinkerpatch這個sdk,並測試補丁ok。
注:參照網上的tinker接入部落格,以及官方文件,自己總是搞不定,說是自己技術渣吧,也可能。反正我參照阿里的文件接入sophix就很順利。
閒言少續,言歸正傳,以下為接入tinkerpatch的大致步驟
- 在專案根build.gradle加入依賴配置
buildscript { repositories { ... maven { url 'https://dl.bintray.com/wemobiledev/maven' } maven { url 'https://dl.bintray.com/tinker/maven' } } dependencies { ... // TinkerPatch 外掛 classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.8" } }
- 在app的build.gradle中,新增依賴
apply from: '../tinkerpatch.gradle' dependencies{ // 若使用annotation需要單獨引用,對於tinker的其他庫都無需再引用 implementation 'com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.8' annotationProcessor 'com.tinkerpatch.tinker:tinker-android-anno:1.9.8' //dex分包,用於tinker implementation "com.android.support:multidex:1.0.3" ... }
- 根據上面的配置,就需要建立換一個tinkerpatch.gradle檔案,路徑與app的builde.gradle同級。一般來說,需要注意兩個位置
- appKey就是你在tinkerpatch平臺上的key
- sevenZip的版本和路徑配置,對應到你本地的路徑。(注意,這裡可能你會下載不到,maven倉庫配置一下阿里的jcenter比較好)
- 7zip檔案的下載,7za這個好多人沒有,需要https://www.7-zip.org/download.html這裡面的download目錄下
7-Zip Extra: standalone console version, 7z DLL, Plugin for Far Manager這一欄。然後解壓到你對應路徑,配置到下面就好。 - com.tencent.mm:SevenZip:1.2.12有時候載入不出來,你就在app的buidle.gradle中新增這個依賴implementation com.tencent.mm:SevenZip:1.2.12來下載,就好。
- 這裡用到一個變數 appversionName需要你配置在gradle中的一個變數,就是app的版本號。可以在根目錄的gradle.properties中配置,如:
appVersionCode=16
appVersionName=2.0.2
注意,有時候AS設定中去掉compile設定項下的–offline引數比較好
import java.util.regex.Matcher
import java.util.regex.Pattern
apply plugin: 'tinkerpatch-support'
/**
* TODO: 請按自己的需求修改為適應自己工程的引數
*/
def bakPath = file("${buildDir}/bakApk/")
tinkerpatchSupport {
/** 可以在debug的時候關閉 tinkerPatch **/
tinkerEnable = true
/** 是否使用一鍵接入功能 **/
reflectApplication = true
/** 是否開啟加固模式,只有在使用加固時才能開啟此開關 **/
protectedApp = false
/** 補丁是否支援新增 Activity (exported必須為false)**/
supportComponent = false
autoBackupApkPath = "${bakPath}"
/** 在tinkerpatch.com得到的appKey **/
appKey = "20155552655555522"
/** 注意: 若釋出新的全量包, appVersion一定要更新 **/
appVersion = appVersionName
baseApkFile = "${bakPath}/app-${appVersionName}.apk"
baseProguardMappingFile = "${bakPath}/app-${appVersionName}-mapping.txt"
baseResourceRFile = "${bakPath}/app-${appVersionName}-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.2.12"
path = "D:\\Android\\7z\\x64\\7za.exe"
}
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
}
}
其他基本不做修改,或者可以根據自身專案配置。
- 在自定義的application中,配置並初始化tinkerpatch:
private ApplicationLike tinkerApplicationLike;//Tinker
@Override
public void onCreate() {
super.onCreate();
//init tinkerpatch
initTinkerPatch();
...
}
@Override
public void attachBaseContext(Context base) {
super.attachBaseContext(base);
//you must install multiDex whatever tinker is installed!
MultiDex.install(base);
}
/**
* 我們需要確保至少對主程序跟patch程序初始化 TinkerPatch
*/
@SuppressLint("LongLogTag")
private void initTinkerPatch() {
// 我們可以從這裡獲得Tinker載入過程的資訊
if (BuildConfig.TINKER_ENABLE) {
tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();
// 初始化TinkerPatch SDK
TinkerPatch.init(tinkerApplicationLike)
.reflectPatchLibrary()
.setPatchRollbackOnScreenOff(true)
.setPatchRestartOnSrceenOff(true)
.setFetchPatchIntervalByHours(3);
// fetchPatchUpdateAndPollWithInterval 與 fetchPatchUpdate(false)
// 不同的是,會通過handler的方式去輪詢
TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
}
}
這裡需要注意的是,如果app使用了多程序,就儘可能只初始化一次。多次初始化有沒有問題,我沒試過。
- 然後在啟動的activity或者你需要的地方自動呼叫在activity的需要的地方,呼叫TinkerPatch.with().fetchPatchUpdate(true);就會聯網請求tinkerpatch平臺上你所釋出的對應版本的補丁。
- 以上配置ok的話,每次打包就會在project/app/build/bakapk/下面生成如app-2.0.2-1012-11-25-31樣式的資料夾,裡面有debug資料夾,下有app-debug.apk以及app-debug-R.txt。
如果你執行的release的build,就是release資料夾下- 在AS的右側Gradle欄目下,找到app-build下執行assembleRelease就能生成release的包。
- 然後將上述的app-release.apk以及app-release-R.txt移動到bakapk目錄下,並更改名稱如app-2.0.2.apk以及app-2.0.2-R.txt。(這實在tinkerpatch.gradle中配置的)。
- 如果開啟了混淆,則也需要生成基礎包的時候把mapping.txt檔案也放到如上的bakapk目錄下。
- 執行AS的Gradle下app–tinker–tinkerPatchRelease的task,就會生成補丁包。在app–build–outputs–apk–tinkerPatch–release下有patch-signed-7z.apk的補丁包。
- 上傳之tinkerpatch平臺,你的專案下,建立專案,建立補丁,然後選擇釋出補丁。
- 此時app啟動,會聯網下載補丁,再次退出啟動的時候,就會應用補丁。有的可能需要啟動三次(冷啟動)。
注意的是,這裡使用的演示是release構建,如果測試debug,你只需要build 對應debug包,然後tinkerpatch也是debug就行。
還有一點說明,好像tinkerpatch這個平臺免費版的下發補丁次數有限制,如果是大型專案,還是自己研究如何使用tinker官方接入方式。或者可以使用阿里的sophix,接入也是很方便。打補丁也方便。