Android資源加載流程及資源替換方案

來源於慕課網。

1 資源加載流程

我們所說的資源是指assets,res目錄下的drawable,layout,color,string,id等等,obtainStyledAttributes。方法調用都是從context到Resources,最後到AssetManager。然後在NativeAssetManager裏處理。見圖。
在這裏插入圖片描述

2 資源替換方案

從資源加載流程可以發現,替換方案從Resources或者AssetManager下手。

2.1 資源包裝流

包裝Resources,當然是對其大部分方法都要包裝。優先去加載我們添加進去的資源。沒有找到,則去走系統的流程。是一個麻煩的過程。
在這裏插入圖片描述

2.2 資源緩存

系統Resources裏獲取資源時,會先從緩存裏獲取,獲取不到則去AssetManager裏找。所以可以通過反射將要加載的資源添加進緩存。這樣的過程很明顯受限於系統緩存的內容,而且由於不同的版本字段會有所變化,適配過程繁瑣。
在這裏插入圖片描述

2.3 AssetManager

這是一種系統的加載方案,總的來說,支持的文件種類最多。
相關連接

該方案使用反射拿到AssetManager裏的addAssetPath方法,添加apk路徑。這樣也會有很多坑,對不同的版本需要進行適配。在創建完activity,也需要將處理好的mResources設置進Context中。

在這裏插入圖片描述

2.4 方案對比

在這裏插入圖片描述

3 資源衝突問題

換膚和插件處理資源衝突問題是不一樣的。換膚是要覆蓋原來的ID的,而插件可能要並存。
換膚資源衝突問題:
1.資源重定向問題
使用動態映射方案:根據ID找到名稱,然後根據名稱和包名找到對應的資源ID。
靜態編譯方案:1.aapt編譯資源時輸入主包的資源ID映射,public.xml;
2.編譯後根據主包映射關係修改皮膚包的resources.arsc .
靜態編譯方案的問題:資源增量靜態對齊。資源查找過程中會有一個資源個數判斷,所以需要讓皮膚包的資源至少大於等於主包的資源數量,不足的部分使用佔位資源。
第二個問題是,資源刪除後如果不用佔位資源,由於資源編排緊湊的這種方式,其他資源會排到刪除的資源位置,這樣查找的資源就會出錯。這裏也需要使用佔位資源。

VirtualApk使用Gradle插件處理
具體思路如下:
根據編譯產生的R.txt文件收集插件中所有的資源
過濾插件資源: 過濾掉在宿主中已經存在的資源
重新設置插件資源的資源ID
刪除掉插件資源目錄下前面已經被過濾掉的資源
重新編排插件: 修改resources.arsc文件中插件資源ID爲新設置的資源ID
重新產生R.java文件

發佈了9 篇原創文章 · 獲贊 5 · 訪問量 5282
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章