介紹
??在介紹Bugly之前睬塌,需要先向大家簡單介紹下一些熱更新的相關(guān)內(nèi)容泉蝌。當(dāng)前市面的熱補(bǔ)丁方案有很多歇万,其中比較出名的有阿里的AndFix、美團(tuán)的Robust以及QZone的超級補(bǔ)丁方案勋陪。但它們都存在無法解決的問題贪磺,這也是Tinker面世的原因。Tinker目前已運(yùn)行在微信的數(shù)億Android設(shè)備上诅愚,相對于其它熱更新方案寒锚,Tinker相對比較優(yōu)秀。
什么是Tinker
??Tinker是微信官方的Android熱補(bǔ)丁解決方案呻粹,它支持動態(tài)下發(fā)代碼壕曼、So庫以及資源,讓應(yīng)用能夠在不需要重新安裝的情況下實現(xiàn)更新等浊。當(dāng)然腮郊,你也可以使用Tinker來更新你的插件。
? | Tinker | QZone | AndFix | Robust |
---|---|---|---|---|
類替換 | yes | yes | no | no |
So替換 | yes | no | no | no |
資源替換 | yes | yes | no | no |
全平臺支持 | yes | yes | yes | yes |
即時生效 | no | no | yes | yes |
性能損耗 | 較小 | 較大 | 較小 | 較小 |
補(bǔ)丁包大小 | 較小 | 較大 | 一般 | 一般 |
開發(fā)透明 | yes | yes | no | no |
復(fù)雜度 | 較低 | 較低 | 復(fù)雜 | 復(fù)雜 |
gradle支持 | yes | no | no | no |
Rom體積 | 較大 | 較小 | 較小 | 較小 |
成功率 | 較高 | 較高 | 一般 | 最高 |
總的來說:
AndFix作為native解決方案筹燕,首先面臨的是穩(wěn)定性與兼容性問題轧飞,更重要的是它無法實現(xiàn)類替換,它是需要大量額外的開發(fā)成本的撒踪;
Robust兼容性與成功率較高过咬,但是它與AndFix一樣,無法新增變量與類只能用做的bugFix方案制妄;
Qzone方案可以做到發(fā)布產(chǎn)品功能掸绞,但是它主要問題是插樁帶來Dalvik的性能問題,以及為了解決Art下內(nèi)存地址問題而導(dǎo)致補(bǔ)丁包急速增大的耕捞。
Tinker的已知問題
Tinker不支持修改AndroidManifest.xml衔掸,Tinker不支持新增四大組件(1.9.0支持新增非export的Activity);
由于Google Play的開發(fā)者條款限制俺抽,不建議在GP渠道動態(tài)更新代碼
在Android N上敞映,補(bǔ)丁對應(yīng)用啟動時間有輕微的影響;
不支持部分三星android-21機(jī)型磷斧,加載補(bǔ)丁時會主動拋出"TinkerRuntimeException:checkDexInstall failed"振愿;
對于資源替換,不支持修改remoteView弛饭。例如transition動畫冕末,notification icon以及桌面圖標(biāo)。
Tinker更多介紹
??對于tinker的詳細(xì)介紹孩哑,感興趣的可以前往查看栓霜,地址:
??https://github.com/Tencent/tinker/wiki
Bugly的介紹
??騰訊 Bugly,是騰訊公司為移動開發(fā)者開放的服務(wù)之一横蜒,面向移動開發(fā)者提供專業(yè)的 Crash 監(jiān)控胳蛮、崩潰分析等質(zhì)量跟蹤服務(wù)销凑。Bugly 能幫助移動互聯(lián)網(wǎng)開發(fā)者更及時地發(fā)現(xiàn)掌控異常,更全面的了解定位異常仅炊,更高效的修復(fù)解決異常斗幼。
Bugly目前包括三大服務(wù):
- 異常上報;
- 運(yùn)營統(tǒng)計抚垄;
- 應(yīng)用升級(包括全量升級和熱更新)蜕窿。
Bugly的熱更新
??熱更新能力是Bugly為解決開發(fā)者緊急修復(fù)線上bug,而無需重新發(fā)版讓用戶無感知就能把問題修復(fù)的一項能力呆馁。Bugly目前采用微信Tinker的開源方案桐经,開發(fā)者只需要集成我們提供的SDK就可以實現(xiàn)自動下載補(bǔ)丁包、合成浙滤、并應(yīng)用補(bǔ)丁的功能阴挣,我們也提供了熱更新管理后臺讓開發(fā)者對每個版本補(bǔ)丁進(jìn)行管理。
為什么使用Bugly熱更新纺腊?
無需關(guān)注Tinker是如何合成補(bǔ)丁的
無需自己搭建補(bǔ)丁管理后臺
無需考慮后臺下發(fā)補(bǔ)丁策略的任何事情
無需考慮補(bǔ)丁下載合成的時機(jī)畔咧,處理后臺下發(fā)的策略
Bugly提供了更加方便集成Tinker的方式
Bugly通過HTTPS及簽名校驗等機(jī)制保障補(bǔ)丁下發(fā)的安全性
豐富的下發(fā)維度控制,有效控制補(bǔ)丁影響范圍
Bugly提供了應(yīng)用升級一站式解決方案
Bugly熱更新SDK的集成
集成Bugly熱更新的詳細(xì)操作可以參考官網(wǎng)的文檔:
https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20171109131920
在這里就不一步一步地結(jié)合如何集成SDK揖膜,總的來說有一下幾個步驟:
工程根目錄build.gradle添加tinker-support插件依賴誓沸;
app module的build.gradle添加SDK依賴;
在app目錄下新建tinker-support.gradle文件壹粟,文件的內(nèi)容文檔有提供拜隧;
初始化SDK,改造application趁仙,雖然也可以不改造application虹蓄,但是兼容性可能會出現(xiàn)問題,官方推薦改造application幸撕;
AndroidManifest.xml配置相關(guān)權(quán)限,如果僅僅只是使用熱更新而不需要使用到全量升級功能外臂,不需要配置BetaActivity和FileProvider坐儿。
混淆配置,在proguard-rules.pro文件中添加Bugly的混淆規(guī)則宋光。
集成熱更新所遇到的相關(guān)問題:
- 文檔中提及使用插件的最新版本可以通過使用lastest.release拉取貌矿,如圖:
但我添加依賴的時候,如下:
buildscript {
repositories {
jcenter()
}
dependencies {
// tinkersupport插件, 其中l(wèi)astest.release指拉取最新版本罪佳,也可以指定明確版本號逛漫,例如1.0.4
classpath "com.tencent.bugly:tinker-support:lastest.release"
}
}
報了找不到該依賴的錯誤,原來是文檔寫錯了赘艳,lastest應(yīng)改成latest才對。
- tinker-support.gradle中缺少supportHotplugComponent這項配置導(dǎo)致打補(bǔ)丁包的時候出現(xiàn)錯誤
??視頻介紹和文檔中都沒有提及到tinker-support.gradle文件tinkerSupport { }中需要添加多supportHotplugComponent這項配置,按照文檔來打補(bǔ)丁的時候却妨,會出現(xiàn)如下錯誤:
看了錯誤提示巢音,老是提示我說manifest was changed,可是我根本沒有改動到manifest肴敛,一直很納悶,直到看了demo后,才發(fā)現(xiàn)需要在tinkerSupport { }中停团,添加supportHotplugComponent這項配置,代碼如下:
tinkerSupport {
...
supportHotplugComponent = true
}
- thinkerId 的指定
??thinkerId需要是唯一的掏熬,在生成基準(zhǔn)包和補(bǔ)丁包時都需要改動佑稠,官方推薦時間用git版本號或版本名生成,這里我自己使用的是versionName_MM-dd-HH-mm-ss這種格式旗芬,版本名+時間戳舌胶,比如1.0.5-1121-11-33-20,這和bakApk下生成基準(zhǔn)包目錄的時間戳類似岗屏,它是app-1121-11-33-20辆琅,這樣查看起來一路了然,查看補(bǔ)丁包的YAPATCH文件也很清晰:
Created-Time: 2017-11-21 11:37:15.673
Created-By: YaFix(1.1)
YaPatchType: 2
VersionName: 1.0.5
VersionCode: 5
From: 1.0.5-1121-11-36-06
To: 1.0.5-1121-11-37-15
From 是基準(zhǔn)包的tinkerId
To 是當(dāng)前補(bǔ)丁包的tinkerId
生成上述格式tinkerId的代碼如下:
tinkerSupport {
...
tinkerId = "${verName()}-${buildTime()}"
...
}
//獲取版本名
def verName() {
def versionPropsFile = file("../version.properties")
if (versionPropsFile.canRead()) {
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
return versionProps['VERSION_NAME']
} else {
throw new GradleException("Could not read gradle.properties")
}
}
//獲取構(gòu)建時間
def buildTime() {
return new Date().format("MMdd-HH-mm-ss", TimeZone.getTimeZone("GMT+8"))
}
需要在工程根目錄下这刷,和gradle.properties文件同目錄下婉烟,新建version.properties文件,用于保存當(dāng)前app的versionCode和versionName暇屋,文件的內(nèi)容:
VERSION_NAME=1.0.5
VERSION_CODE=4
既然將versionCode和versionName配置在properties文件中似袁,那么app module的gradle文件中,defaultConfig{}中指定版本名和版本號直接使用該配置
android {
...
defaultConfig {
...
versionCode verCode()
versionName verName()
...
}
}
獲取版本號的方法verCode(),代碼如下:
//獲取版本號
def verCode() {
def versionPropsFile = file("../version.properties")
if (versionPropsFile.canRead()) {
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def int verCode = versionProps['VERSION_CODE'].toInteger()
return verCode;
} else {
throw new GradleException("Could not read gradle.properties")
}
}
Bugly Q&A
??到這里Bugly熱更新的相關(guān)介紹就到此為止了咐刨,在這里向大家簡單介紹了Bugly集成是使用中遇到的問題和相關(guān)的建議昙衅,官方也提供了常見問題解決的介紹:
Demo源碼
https://github.com/chaychan/BuglyHotFixDemo
支持和鼓勵
如果你喜歡我的文章的話,可以關(guān)注我的博客定鸟,感謝大家一直以來給我的支持和鼓勵而涉,你們的每一次喜歡和打賞,使我寫文章更有動力联予。