Atlas框架介紹集成(一)


  Atlas是什么?

     Atlas是一個Android客戶端容器框架,主要提供了組件化、動態性、解耦化的支持。支持在編碼期、Apk運行期以及后續運維修復期的各種問題。

  • 在工程期,實現工程獨立開發,調試功能,工程模塊的獨立。
  • 在運行期間,實現完整的組件生命周期映射,類隔離等機制。
  • 在運維期間,提供快速增量的更新修復功能,快速升級。

     Atlas是工程期和運行期共同起作用的框架,它盡量將一些工作放在工程期,這樣保證運行期的簡單、穩定。

  Atlas組件化實現

   

 

 

 

 

  上圖是手機淘寶的apk,第一層目錄上與標准的apk是完全一樣的。在App會有很多的so文件,每個送文件如果解開來看它的結構類似於完整的apk,但本身不能獨立運行,它跟很多傻簡化的差別是在運行期,它是運行在整個容器里,每一個組件都是獨立的Bundle。

從模塊來划分,手淘APK可以分為兩層,上層是經過拆分的業務Bundle,掃碼、評價、詳情,各個業務之間可以進行功能的調用,可以通過路由調度到其他業務方。下層是共享的底層中間件,向業務方開放各種能力,如網絡庫、圖片庫等,會在容器里進行統一地把控,這樣做的好處是包做到盡可能小,第二是性能佳。

這一塊是Atlas的整體設計,分為五層:

第一層稱之為Hack層,包括OS Hack toolkit & verifier,這里對系統能力做一些擴展,然后做一些安全校驗。

第二層是Bundle Framework,就是的容器基礎框架,提供Bundle管理、加載、生命周期、安全等一些最基本的能力。

第三層是運行期管理層,包括清單,會把所有的Bundle和它們的能力列在一個清單上,在調用時方便查找;另外是版本管理,會對所有Bundle的版本進行管理;再就是代理,這里就是和業界一些插件化框架機制類似的地方,會代理系統的運行環境,讓Bundle運行在的容器框架上;然后還有調試和監控工具,是為了方便工程期開發調試。

第四層是業務層了,這里向業務方暴露了一些接口,如框架生命周期、配置文件、工具庫等等。

最上面一層是應用接入層,就是的業務代碼了。

所以Atlas作為一個框架提供了相對完整的能力,業務層的開發可以在框架生命周期的各個環節做一些自定義的動作,也可以自由的調用系統、框架,乃至其它組件釋放的能力

 

組件化技術細節

關於Bundle的生命周期會提供細粒度的節點,比如下面是一個Bundle從加載到運行的周期:

  • startInstall:開始加載。這個時候框架會做一些拷貝文件、釋放lib、加載Bundle的事情;
  • Installed:加載完畢。這時框架會注入資源路徑,創建class loader;
  • resolved:解析完畢,框架會檢查組件配置是否合法,是否能被解析;
  • active:運行組件,即開始運行組件Bundle;
  • started:運行成功。

組件化涉及到的第一個問題是Manifest處理,一個是因為來源很多,有宿主Manifest、Aar Manifest以及組件Manifest,另外不同組件的Manifest經常發生變化,要求靈活地去處理。這里的做法是在工程期將所有的Manifest進行Merge操作,這里需要注意的是Bundle的依賴單獨Merge,因為這里涉及到依賴仲裁的問題。最后解析各個Bundle的Merge Manifest,得到整包的BundleInfoList,就是上面提到的Bundle信息清單。

第二個是類加載,這里利用Delegate ClassLoader來動態加載組件的類。Delegate ClassLoader先查找宿主Bundle的PathClassLoader,然后根據前面的BundleList找到對應的BundleClassLoader.

 

第三個是資源,會用自己的DelegeteResources替換掉系統的resource,Bundle的資源會逐個在安裝的時候添加到AssertPath,由於添加Bundle的順序非固定,不分區會導致資源查找錯亂。

另外,Dalvik和ART上的資源查找過程順序是不一樣的,加上小米等系統會重寫自己的resources,所以會適配不同的機型,往后追加AssetsPath或者往前追加,系統AssetManager是個單例,默認往后追加,如果往前追加,則需要重新創建AssetsManager對象,同樣主dex動態部署的時候要達到替換原有resource的目的,必須保證插入順序與查找順序一致。

還有需要注意的是,每次更新resourceTable的時候,必須保證apkresource,runtime的系統resource,例如webview,bundle resource都已經添加成功,而且唯一,順序正確。

不同Bundle的資源可能發生命名沖突,是用了一種相對來說簡單的方法,將各自的Bundle分配成不同的ID,保證所有的業務資源不會產生沖突,盡量將問題放到工程期解決。在很多代碼里,通過反射來調用整個資源,在5.0以上的系統是沒有問題的,它只找第一個,對業務代碼而言,原來是怎么寫的,今天還是怎么去寫。

關於組件化性能這一部分,引入了按需加載,因為手淘APK有70多個Bundle,每個用戶真正用的時候只需要5或10個,所以不需要加載所有的Bundle。Bundle之間進行隔離,通過Android四大原生組件進行交互,這樣Bundle之間可以比較好的解耦。所有調用的入口都是基於BundleInfolist去做的,根據這個清單信息,得到組件所在Bundle,如果需要加載,就進行install、dexopt等操作。

另外,對於解決組件依賴問題,定義了兩種新的組件格式Awb(業務Bundle)和solib(so庫),前者與AAR一致,不過不添加本地lib,在構建的時候做依賴仲裁區分,后者是Native so庫的依賴。Awb其實就是AAR,只是后綴修改了,如果你的包放在宿主Bundle就用AAR,如果是組件Bundle就用Awb。

對於業務Bundle的依賴,在構建期會將宿主Bundle和業務Bundle及其依賴分別打包,然后按照最短路徑、第一聲明原則進行樹狀仲裁,得到每個Bundle需要的依賴,在打包的時候會將依賴庫放到各自的Bundle里去。

最后是APK構建,對它做了比較大的調整。上面的圖中,其實左邊這一部分是一個標准的APK的構建過程,包括處理,編譯,到簽名的過程。這個不同的地方是多了Awb需要特殊處理,其中Awb的資源根據宿主的resource.ap_和包內資源構建,R文件由Bundle R資源和宿主R資源合並而來,然后對Aapt進行了修改,對每個awb分配不同的packageId,然后進行統一混淆,生產各個AWB的Dex,打包為APK,簽名之后復制到libs,改名為so文件,然后合並到taobao APK. 這就是組件化的整個過程。

 

Atlas動態化

在一個容器框架內,組件化和動態化是相輔相成的,組件只是解決了解耦的問題,但如果想要隨時發包,就必須讓容器框架具備動態化能力。在完成了Atlas的組件化之后,做了動態化的支持。動態化的好處一個是包的大小縮減,可以將一些包在運行后下載到應用中,另一個是具備動態發版和修復能力。

增量動態化方案

Atlas提供了動態部署的能力,主要目標是動態業務發布,以及問題修復。它基於手淘自研差量算法,主Bundle基於ClassLoader機制,業務Bundle基於差量merge,支持全業務類型。

另外,Atlas也支持Andfix作為插件使用,目標是快速故障修復,它的原理基於Native hook,主要做方法的修改,在實際中可以兩個一起用。在工程構建期適配之后,可以做到一套代碼兩套方案通用。

自研動態部署功能實現原理,首先,對於Dex Patch的生成,通過修改Dex的字節碼實現,將Dex文件轉為Smali,對其中的ClassDef和ClassDataMethod結構體進行分析,可以實現刪除、新增、修改類,然后通過Diff處理得到差量文件,再通過Merge處理即生成補丁。

其次是整個資源Patch的生成,分為兩塊,一個是業務Bundle,本來是一個不斷加載的過程,它實現起來會比較簡單,通過Md5 diff/BSDiff即可得到。對於主Bundle,因為安卓本身有一個限制,所有的資源必須得在base包里,新增一個資源是不生效的。所以一個做法是在打包的時候預留很多空資源。另外更新已有的資源則通過資源覆蓋來完成。

最后,如果新加業務的話,會新加Activity,的做法首先在Manifest預埋一個StubActivity,然后在Instrumentation.execStartActivity()階段進行替換,同時配合Intent setFlag模擬Activity launch mode並繼續startActivity,接着System_server進程進行處理,更新ActivityStack,創建binder,並通知ActivityThread進行實例創建,最后在ActivityThread的handler里面進行攔截,更新ActivityInfo等信息,創建目標Activity。

另外在工程實踐上,因為補丁的生成會涉及到Dex和資源的基線,會在部署的時候,每次發布APK包同步發布AP(基線包)到Maven,AP基線包里是所有影響基線的文件,第一是安卓APK,第二是Mapping.txt,最后是Dependency.txt,這樣的話整個構建的速度會非常的快。

所以這種方式,版本的升級是不同的方式。比如今天手淘的詳情要更新,會發布版本,這個版本可能不是到應用市場的版本,而是一個Patch包。業務版本的動態部署,是同步的,5.3.0到5.3.1到5.3.2,這樣一個好處是只要容器版本沒有升級,只要有需求,patch就可以一直升級,而且是無感知的差量升級。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM