android上的主題切換,Android從M開始加入了動(dòng)態(tài)資源overlay機(jī)制 runtime resource overlay(RRO)丛楚,這個(gè)是sony貢獻(xiàn)的,實(shí)現(xiàn)機(jī)制如下圖,就是在框架中建立一套資源ID映射表呀伙,通過這個(gè)映射表動(dòng)態(tài)切換不同的主題。
具體的代碼實(shí)現(xiàn)在 OverlayManagerService 代碼中添坊,
代碼的架構(gòu)如下剿另,IdmapManager是生成對應(yīng)的映射表。
- <pre>
Android framework
| ^
. . . | . . . . | . . . .
. | | .
. AIDL, broadcasts .
. intents | .
. | | . . . . . . . . . . . .
. v | . .
. OverlayManagerService . OverlayManagerTests .
. \ . / .
. (1) \ . / (3) .
. . . . . . . . . . \ . . . / . . . . . . . . .
. \ / .
. (2) \ / .
. OverlayManagerServiceImpl .
. | | .
. | | .
. OverlayManagerSettings IdmapManager .
. .
. . . . . . . . . . . . . . . . . . . . . .
- </pre>
通過 adb shell dumpsys overlay 命令可以查看系統(tǒng)里面的overlay包以及包的狀態(tài)贬蛙。
下面命令可以設(shè)置每個(gè)資源包的狀態(tài)雨女,設(shè)置成enable就會(huì)立即生效,(具體命令可以到代碼里面查到shellcommand)
adb exec-out cmd overlay enable com.android.systemui.theme.dark
實(shí)現(xiàn)方法阳准,把新主題的資源和目標(biāo)apk的資源完全一致的ID戚篙,生成一套應(yīng)用的資源,
<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">RRODemo</string> <string name="hello_world">這是原生應(yīng)用的資源</string></resources>
overlay資源:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="hello_world">這是rro加載的資源</string></resources>
這里需要替換的就是hello_world的顯示內(nèi)容,這個(gè)名字必須和待替換的資源名(hello_world)相同
manifest按照如下方式實(shí)現(xiàn):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui.theme.dark"
android:versionCode="1"
android:versionName="1.0">
<overlay android:targetPackage="com.android.systemui" android:priority="1"/>
<application android:label="@string/sysui_overlay_dark" android:hasCode="false"/>
</manifest>
注意這個(gè)apk需要在大環(huán)境里面編譯溺职,編譯的mk按照如下方式編寫岔擂,注意簽名。
LOCAL_PATH:= (CLEAR_VARS)
LOCAL_RRO_THEME := SysuiDarkTheme
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_PACKAGE_NAME := SysuiDarkThemeOverlay
LOCAL_SDK_VERSION := current
include $(BUILD_RRO_PACKAGE)
生成apk后push到 system/vendor/overlay里面浪耘。 就可以了乱灵。