Android熱更新初探,Bugly熱更新的集成和使用(讓你的應用輕鬆具備熱更新能力)

本篇文章已授權微信公衆號 guolin_blog (郭霖)獨家發佈

介紹

  在介紹Bugly之前,需要先向大家簡單介紹下一些熱更新的相關內容。當前市面的熱補丁方案有很多,其中比較出名的有阿里的AndFix、美團的Robust以及QZone的超級補丁方案。但它們都存在無法解決的問題,這也是Tinker面世的原因。Tinker目前已運行在微信的數億Android設備上,相對於其它熱更新方案,Tinker相對比較優秀。

什麼是Tinker

  Tinker是微信官方的Android熱補丁解決方案,它支持動態下發代碼、So庫以及資源,讓應用能夠在不需要重新安裝的情況下實現更新。當然,你也可以使用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
性能損耗 較小 較大 較小 較小
補丁包大小 較小 較大 一般 一般
開發透明 yes yes no no
複雜度 較低 較低 複雜 複雜
gradle支持 yes no no no
Rom體積 較大 較小 較小 較小
成功率 較高 較高 一般 最高

總的來說:

  1. AndFix作爲native解決方案,首先面臨的是穩定性與兼容性問題,更重要的是它無法實現類替換,它是需要大量額外的開發成本的;

  2. Robust兼容性與成功率較高,但是它與AndFix一樣,無法新增變量與類只能用做的bugFix方案;

  3. Qzone方案可以做到發佈產品功能,但是它主要問題是插樁帶來Dalvik的性能問題,以及爲了解決Art下內存地址問題而導致補丁包急速增大的。

Tinker的已知問題

  1. Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大組件(1.9.0支持新增非export的Activity);

  2. 由於Google Play的開發者條款限制,不建議在GP渠道動態更新代碼

  3. 在Android N上,補丁對應用啓動時間有輕微的影響;

  4. 不支持部分三星android-21機型,加載補丁時會主動拋出”TinkerRuntimeException:checkDexInstall failed”;

  5. 對於資源替換,不支持修改remoteView。例如transition動畫,notification icon以及桌面圖標。

Tinker更多介紹

  對於tinker的詳細介紹,感興趣的可以前往查看,地址:

  https://github.com/Tencent/tinker/wiki

Bugly的介紹

  騰訊 Bugly,是騰訊公司爲移動開發者開放的服務之一,面向移動開發者提供專業的 Crash 監控、崩潰分析等質量跟蹤服務。Bugly 能幫助移動互聯網開發者更及時地發現掌控異常,更全面的瞭解定位異常,更高效的修復解決異常。

Bugly目前包括三大服務:

  1. 異常上報;
  2. 運營統計;
  3. 應用升級(包括全量升級和熱更新)。

Bugly的熱更新

  熱更新能力是Bugly爲解決開發者緊急修復線上bug,而無需重新發版讓用戶無感知就能把問題修復的一項能力。Bugly目前採用微信Tinker的開源方案,開發者只需要集成我們提供的SDK就可以實現自動下載補丁包、合成、並應用補丁的功能,我們也提供了熱更新管理後臺讓開發者對每個版本補丁進行管理。

爲什麼使用Bugly熱更新?

  • 無需關注Tinker是如何合成補丁的

  • 無需自己搭建補丁管理後臺

  • 無需考慮後臺下發補丁策略的任何事情

  • 無需考慮補丁下載合成的時機,處理後臺下發的策略

  • Bugly提供了更加方便集成Tinker的方式

  • Bugly通過HTTPS及簽名校驗等機制保障補丁下發的安全性

  • 豐富的下發維度控制,有效控制補丁影響範圍

  • Bugly提供了應用升級一站式解決方案

Bugly熱更新SDK的集成

集成Bugly熱更新的詳細操作可以參考官網的文檔:

https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20171109131920

在這裏就不一步一步地結合如何集成SDK,總的來說有一下幾個步驟:

  1. 工程**根目錄**build.gradle添加tinker-support插件依賴;

  2. app module的build.gradle添加SDK依賴;

  3. app目錄下新建tinker-support.gradle文件,文件的內容文檔有提供;

  4. 初始化SDK,改造application,雖然也可以不改造application,但是兼容性可能會出現問題,官方推薦改造application;

  5. AndroidManifest.xml配置相關權限,如果僅僅只是使用熱更新而不需要使用到全量升級功能,不需要配置BetaActivity和FileProvider

  6. 混淆配置,在proguard-rules.pro文件中添加Bugly的混淆規則

集成熱更新所遇到的相關問題:

  • 文檔中提及使用插件的最新版本可以通過使用lastest.release拉取,如圖:

image

但我添加依賴的時候,如下:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // tinkersupport插件, 其中lastest.release指拉取最新版本,也可以指定明確版本號,例如1.0.4
        classpath "com.tencent.bugly:tinker-support:lastest.release"
    }
}

報了找不到該依賴的錯誤,原來是文檔寫錯了,lastest應改成latest纔對。

  • tinker-support.gradle中缺少supportHotplugComponent這項配置導致打補丁包的時候出現錯誤

  視頻介紹和文檔中都沒有提及到tinker-support.gradle文件tinkerSupport { }中需要添加多supportHotplugComponent這項配置,按照文檔來打補丁的時候,會出現如下錯誤:

image

看了錯誤提示,老是提示我說manifest was changed,可是我根本沒有改動到manifest,一直很納悶,直到看了demo後,才發現需要在tinkerSupport { }中,添加supportHotplugComponent這項配置,代碼如下:

tinkerSupport { 

    ...

    supportHotplugComponent = true

}
  • thinkerId 的指定

  thinkerId需要是唯一的,在生成基準包和補丁包時都需要改動,官方推薦時間用git版本號或版本名生成,這裏我自己使用的是versionName_MM-dd-HH-mm-ss這種格式,版本名+時間戳,比如1.0.5-1121-11-33-20,這和bakApk下生成基準包目錄的時間戳類似,它是app-1121-11-33-20,這樣查看起來一路瞭然,查看補丁包的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 是基準包的tinkerId
To 是當前補丁包的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")
    }
}

//獲取構建時間
def buildTime() {
    return new Date().format("MMdd-HH-mm-ss", TimeZone.getTimeZone("GMT+8"))
}

需要在工程根目錄下,和gradle.properties文件同目錄下,新建version.properties文件,用於保存當前app的versionCode和versionName,文件的內容:


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熱更新的相關介紹就到此爲止了,在這裏向大家簡單介紹了Bugly集成是使用中遇到的問題和相關的建議,官方也提供了常見問題解決的介紹:

   Bugly Android 熱更新常見問題

如果裏面找不到你想要的,可以聯繫他們的客服的QQ,但是客服幾乎不回答,有點無奈,客服QQ自動回覆推薦去他們的論壇留言,可是發現該論壇禁止註冊了,有點悲催。幾番波折後,終於在他們的新浪微博上找到了希望:

image

發現了他們提供技術支持的QQ討論羣,羣號爲: 130979883,現在已經加入了羣裏,向Bugly的技術人員詢問了自己的相關疑問。

Demo源碼

https://github.com/chaychan/BuglyHotFixDemo

支持和鼓勵

如果你喜歡我的文章的話,可以關注我的博客,感謝大家一直以來給我的支持和鼓勵,你們的每一次喜歡和打賞,使我寫文章更有動力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章