【原】Android熱更新開源項目Tinker源碼解析系列之三:so熱更新

本系列將從如下三個方面對Tinker進行源碼解析:html

  1. Android熱更新開源項目Tinker源碼解析系列之一:Dex熱更新
  2. Android熱更新開源項目Tinker源碼解析系列之二:資源文件熱更新
  3. Android熱更新開源項目Tinker源碼解析系類之三:so文件熱更新

 

轉載請標明本文來源:http://www.cnblogs.com/yyangblog/p/6252855.html
更多內容歡迎star做者的github:https://github.com/LaurenceYang/article
若是發現本文有什麼問題和任何建議,也隨時歡迎交流~git

首先講下Android裏面關於so的加載的兩種方式:github

方式一:System.loadLibrary, 這種方式傳入的是so的名字,會直接從系統的目錄去加載so文件,系統的路徑包括/data/data/${package_name}/lib、/system/lib、/vender/lib等這類路徑。算法

方式二:System.load, 這種方式傳入的是so的絕對路徑,直接從這個路徑加載so文件。框架

 

Tinker的so文件熱更新的原理就是經過方式二,直接加載新的so實現的。spa

相對於Dex和資源的更新,是否是簡單不少。code

 

so文件的熱更新流程同dex、資源文件同樣,包含補丁生成,補丁合成,補丁加載三個部分。htm

 

生成補丁時比較新舊so文件使用BSdiff算法生成補丁包,blog

而後在下發補丁成功後根據BSpatch算法將補丁包和舊的library合成新的library,資源

並將更新後的Library庫文件保存在tinker下面的目錄下,

這個目錄就是/data/data/${package_name}/tinker/lib。

而後在加載的時候直接經過System.load加載該目錄下面的so文件。

具體的源碼再也不作闡述。

 

須要注意的是,Tinker中so的熱更新對用戶並非無感的,須要用戶自發的去加載本身須要的庫文件,下面是tinker的wiki裏關於這方面的描述:

可是Tinker並無直接將補丁的lib路徑添加到DexPathList中,理論上這樣能夠作到程序徹底沒有感知的對Library文件做補丁。這裏主要是由於在多abi的狀況下,某些機器獲取的並不許確。

因此想要加載最新的庫,須要本身使用TinkerInstaller.load*Library去加載庫文件,它會自動嘗試先去Tinker中的庫文件加載,加載不成功會調用System.loadLibrary調用系統的庫文件。

1 //load lib/armeabi library
2 TinkerInstaller.loadArmLibrary(getApplicationContext(), "stlport_shared"); 3 //load lib/armeabi-v7a library
4 TinkerInstaller.loadArmV7Library(getApplicationContext(), "stlport_shared");

 

另外,對於第三方庫文件的加載,Tinker沒法干預其加載時機,可是隻要在咱們的代碼提早加載第三方的庫文件便可。

若想對第三方代碼的庫文件更新,可先使用TinkerInstaller.load*Library對第三方庫作提早的加載!

當前使用方式彷佛並不能作到開發者透明,這是由於Tinker想盡可能少的去hook系統框架減小兼容性的問題。

 

到此,tinker的源碼解析系列到此結束。

本系列從dex,資源文件和so的補丁生成,補丁合成和補丁加載角度出發,作了一個簡要的流程分析。

由於本身水平有限,不少地方也沒有太過深刻。

對tinker感興趣的同窗能夠到tinker的官方github去看更多的文檔。

也歡迎你們多多拍磚。

 

轉載請標明本文來源:http://www.cnblogs.com/yyangblog/p/6252855.html
更多內容歡迎star做者的github:https://github.com/LaurenceYang/article
若是發現本文有什麼問題和任何建議,也隨時歡迎交流~

 

 下一篇文章將對在實際使用tinker過程當中所須要考慮的問題作一個闡述。

相關文章
相關標籤/搜索