Android熱更新介紹,Bugly熱更新的集成和使用

1、爲什麼要用熱更新
      開發人員一定深有體會,上線的app突然發現一個bug影響用戶使用,就需要重新打包App、測試、向各個應用市場和渠道換包、提示用戶升級、用戶下載、覆蓋安裝等步驟,用戶還會抱怨怎麼又升級了,頻繁升級對用戶體驗也不好。就想到能不能像服務器哪樣,如果有問題就替換某個文件重啓,用戶就可以繼續使用了。這就衍生出熱修復概念產生。

2、什麼是熱修復
      熱修復通俗說就是打補丁,讓用戶在無感的情況下更新,修復不用重新發版。

3、熱修復原理

      在熱修復出現之前,一個已經上線的app中如果出現了bug,即使是一個非常小的bug,不及時更新的話有可能存在風險,若要及時更新就得將app重新打包發佈到應用市場後,讓用戶再一次下載,這樣就大大降低了用戶體驗,當熱修復出現之後,這樣的問題就不再是問題了。

目前較火的熱修復方案大致分爲兩派,分別是:

  1. 阿里系:DeXposed、andfix:從底層二進制入手(c語言)。
  2. 騰訊系:tinker:從java加載機制入手。

其實,不管是哪種熱修復方案,肯定是如下幾個步驟:

  1. 下發補丁(內含修復好的class)到用戶手機,即讓app從服務器上下載(網絡傳輸)
  2. app通過"某種方式",使補丁中的class被app調用(本地更新)

其中第二種方式,與安卓的類加載過程切入,過程簡介如下:

安卓的類加載器在加載一個類時會先從自身DexPathList對象中的Element數組中獲取(Element[] dexElements)到對應的類,之後再加載。採用的是數組遍歷的方式,不過注意,遍歷出來的是一個個的dex文件。

  在for循環中,首先遍歷出來的是dex文件,然後再是從dex文件中獲取class,所以,我們只要讓修復好的class打包成一個dex文件,放於Element數組的第一個元素,這樣就能保證獲取到的class是最新修復好的class了(當然,有bug的class也是存在的,不過是放在了Element數組的最後一個元素中,所以沒有機會被拿到而已)。

更多可參考這篇文章。https://www.jianshu.com/p/cb1f0702d59f

 

4、什麼是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體積     較大      較小         較小       較小
成功率        較高      較高         一般        最高


總的來說:

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

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

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

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

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

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

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

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

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

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

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

Bugly目前包括三大服務:

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


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,總的來說有一下幾個步驟:
工程根目錄build.gradle添加tinker-support插件依賴;

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

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

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

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

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

集成熱更新所遇到的相關問題:
文檔中提及使用插件的最新版本可以通過使用lastest.release拉取,如圖:


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

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這項配置,按照文檔來打補丁的時候,會出現如下錯誤:

看了錯誤提示,老是提示我說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自動回覆推薦去他們的論壇留言,可是發現該論壇禁止註冊了,有點悲催。幾番波折後,終於在他們的新浪微博上找到了希望:

發現了他們提供技術支持的QQ討論羣,羣號爲: 130979883,現在已經加入了羣裏,向Bugly的技術人員詢問了自己的相關疑問。
--------------------- 
作者:ChayChan 
原文:https://blog.csdn.net/Chay_Chan/article/details/78591621 
 

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