文章目錄
- 前言
- 編譯方式
- 前提
- 靜態Overlay
- res 目錄
- 運行時Overlay
- 與SRO的區別
- 配置步驟
- 存在的問題
- RRO注意事項
- 資源ID
- 總結
- 關于原始碼中的device.mk
前言
Android Overlay是一種資源替換機制,它能在不重新打包apk的情況下,實作資源檔案的替換(res目錄非assert目錄),Overlay又分為靜態Overlay(Static Resource Overlay)與運行時Overlay(Runtime Resource Overlay),他有自己的局限性,它無法替換java檔案,
Android Override是一種檔案替換方式,注意是檔案替換,他有自己的局限性,它無法覆寫一個APK中的某一個檔案,但是可以直接覆寫APK,
編譯方式
編譯型別:mmm mm m
source build/envthup.sh
brunch -b -f (override檔案打入原始碼中)
lunch
make
adb sync
framework-res.apk
framework-res__auto_generated_rro_product.apk
adb shell sync 命令:
1,在shell中執行
2,將記憶體緩沖區中的資料 寫入到磁盤
adb sync 命令:
命令意思:同步更新/data/或/system/下的資料
命令用法:adb sync [directory]
如果不指定目錄,將同步更新/data/和/system
前提
Overlay需要在原始碼編譯環境中完成
靜態Overlay
靜態Overlay,簡稱為SRO,發生在編譯時,需要在Android系統原始碼環境中進行配置,\device\sample\products\backup_overlay.mk

res 目錄
| 目錄Directory | 資源型別Resource Types |
|---|---|
| res/anim/ | XML檔案,它們被編譯進逐幀影片(frame by frame animation)或補間影片(tweened animation)物件 |
| res/drawable/ | .png、.9.png、.jpg檔案,它們被編譯進以下的Drawable資源子型別中:要獲得這種型別的一個資源,可以使用Resource.getDrawable(id) 位圖檔案 9-patches(可變尺寸的位圖)為了獲取資源型別,使用mContext.getResources().getDrawable(R.drawable.imageId) |
| res/layout/ | 被編譯為螢屏布局(或螢屏的一部分)的XML檔案,參見布局宣告(Declaring Layout) |
| res/values/ | 可以被編譯成很多種型別的資源的XML檔案, |
| res/xml/ | 任意的XML檔案,在運行時可以通過呼叫Resources.getXML()讀取, |
| res/raw/ | 直接復制到設備中的任意檔案,它們無需編譯,添加到你的應用程式編譯產生的壓縮檔案中,要使用這些資源,可以呼叫Resources.openRawResource(),引數是資源的ID,即R.raw.somefilename, |
注意: 不像其他的res/檔案夾,它可以保存任意數量的檔案,這些檔案保存了要創建資源的描述,而不是資源本身,XML元素型別控制這些資源應該放在R類的什么地方,
盡管這個檔案夾里的檔案可以任意命名,不過下面使一些比較典型的檔案(檔案命名的慣例是將元素型別包含在該名稱之中):
array.xml 定義陣列
colors.xml 定義color drawable和顏色的字串值(color string values),
使用Resource.getDrawable()和Resources.getColor()分別獲得這些資源,
dimens.xml 定義尺寸值(dimension value),使用Resources.getDimension()獲得這些資源,
strings.xml 定義字串(string)值,使用Resources.getString()或者
Resources.getText()獲取這些資源,
getText()會保留在UI字串上應用的豐富的文本樣式,
styles.xml 定義樣式(style)物件,
放在這里的影像資源可能會被aapt工具自動地進行無損壓縮優化,比如,一個真彩色但并不需要256色的PNG可能會被轉換為一個帶調色板的8位PNG,這使得同等質量的圖片占用更少的資源,所以我們得意識到這些放在該目錄下的二進制影像在生成時可能會發生變化,如果你想讀取一個影像位流并轉換成一個位圖(bitmap),請把影像檔案放在res/raw/目錄下,這樣可以避免被自動優化,
運行時Overlay
運行時Overlay,簡稱RRO,顧名思義,該機制的資源替換發生在運行時,
與SRO的區別
- RRO能直接定制替換第三方APK的資源,而不需要其原始碼,SRO如上節所述,則需要對應APK的原始碼才能完成,一般而言,第三方是不會提供專案原始碼的,
- RRO的編譯結果會得到一個xxx_overlay.apk,加上原專案的apk,總共會有2個apk,而SRO最終只會得到一個已經完成資源替換的apk,得到的overlay.apk可以視為一個正常的apk,因為它能被安裝,含有自己的AndroidManifest.xml檔案,當然正常下,overlay.apk是不含有執行代碼的,
- RRO不能替換AndroidManifest.xml檔案及reference resource 型別的檔案,如layout、anim、xml目錄中的xml檔案,雖然RRO具有自己的AndroidManifest.xml檔案,但它卻不能替換源專案中的AndroidManifest.xml檔案,關于layout目錄中的xml檔案,SRO是可以替換的,
配置步驟
下面以創建Launcher的RRO為例進行說明
創建一個新專案,包名命名為com.android.launcher.overlay,事實上包名可以隨意命名,這樣命名可讀性高,一看包名就知道是哪個專案的overlay,
編輯overlay專案的AndroidManifest.xml檔案,檔案內容如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher.overlay">
<overlay android:targetPackage="com.android.launcher" android:priority="1"/>
</manifest>
其中,android:targetPackage:需要overlay的專案的包名
android:priority:設定overlay.apk的優先級,值越大,優先級越高,用于存在多個overlay.apk情況下的判斷,
替換相對應路徑下的res資源
撰寫mk檔案,編譯、打包、簽名,并將生成的overlay.apk輸出到/vendor/overlay目錄下,Android 8.0以后 其中簽名需要與源專案簽名一致,否則不會生效,
存在的問題
把app放到vendor/overlay下面以后,還要activate,默認是disable的
activate有兩種方式:
一種是overlay的app的清單檔案中,overlay標簽寫 isStatic=“true”
一種是加系統屬性ro.boot.vendor.overlay.theme=overlay的app的包名,分號分割
PS:沒有原始碼環境,或者不懂mk檔案,可以通過root手機,直接將我們生成的overlay.apk直接push到/vendor/overlay目錄下,來測驗RRO機制,
部分廠商可能更改了路徑,可通過adb shell pm path xxxx.overlay 查找到路徑,前提是手機中已經安裝了某個overlay的apk,
RRO注意事項
- 生成的apk需要指定輸出到vendor下才會生效
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/overlay
include $(BUILD_PACKAGE) - 由于overlay替換的是資源檔案,所以必須呼叫res目錄資源檔案
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - android:priority范圍是0-9999,過萬就不生效了 (越大優先級越高)
單個overlay包
當對應專案只有一個overlay包時,那么查找資源時,會先從overlay.apk中進行查找,查找成功直接回傳,反之則從app中查找,
多個overlay包
當對應專案具有多個overlay包時,會按照overlay包的優先級從高到底依次進行查找,如果overlay包都查找失敗,才會到app中進行查找,
以訪問R.drawable.ic_01為例,會先從overlay1包先查找,因為其優先級最高,查找到則直接回傳,
如果訪問R.drawable.ic_02,先從overlay1查找,查找失敗,接著從overlay2中查找,查找到直接回傳,
如果訪問R.drawable.ic_03,依次從overlay1,overlay2中查找,查找失敗,最后會從app中查找到,并回傳,

資源ID
資源檔案在打包之后,會在R.java檔案中生成一個對應的int型別資源id,這個id遵循以下的規則:
0xppttiiii
其中,
pp:01表示是系統資源,7f表示是應用資源
tt:用于表示資源型別,如string、array、圖片資源等
iiii:用于表示相同型別的不同資源
總結
SRO實際上只是利用AAPT重新打包,發生在編譯時;RRO,才是overlay機制的關鍵,其本質是Android系統的動態資源查找機制,
overlay新增一個資源通過add-resource 方式添加
<!-- add for status bar system icon define -->
<add-resource type="string" name="status_bar_child_mode"/>
<string translatable="false" name="status_bar_child_mode">child_mode</string>
關于原始碼中的device.mk

這里有一個overlay的先后問題,比較重要,由高到底
- DEVICE_PACKAGE_OVERLAYS
- PRODUCT_PACKAGE_OVERLAYS–級別最高,也就是優化用PRODUCT_PACKAGE_OVERLAYS中的overlays(高于DEVICE_PACKAGE_OVERLAYS)
- PRODUCT_ENFORCE_RRO_TARGETS
- PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS
在Android O上面 Google增加了一個enforced RRO的方法,可以把之前的build time overlay強制轉換成runtime resource overlay.如果overlay的是framework-res的資源包,那麼會自動生成一個file在/vendor/overlay/framework-res__auto_generated_rro.apk.里面會包含overlay的資源,也就是說,對于加了PRODUCT_ENFORCE_RRO_TARGETS的模塊,便由SRO變成RRO模式,如果仍然想保持SRO模式,就需要使用到PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS變數,
具體原因見此文章
另外,出于安全性考慮,谷歌公司在Android 8.0版本后,不僅要求Overlay apk 和Target apk這兩個apk中的簽名–致,還需要在源專案Targetapk中的AndroidManifest. xml檔案中宣告具有android.permission. CHANGE_ OVERLAY_ PACKAGES 的權限,
代碼中存在的RRO.apk

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/300275.html
標籤:其他
上一篇:Android studio創建hello world
下一篇:【Android 教程系列第 9 篇】升級 Android Studio 到 Arctic Fox 2020.3.1 后,使用搜索功能時出現中文亂碼的問題
