android動態主題切換(RRO 技術)


android上的主題切換,Android從M開始加入了動態資源overlay機制 runtime resource overlay(RRO),這個是sony貢獻的,實現機制如下圖,就是在框架中建立一套資源ID映射表,通過這個映射表動態切換不同的主題。

 
image.png

具體的代碼實現在 OverlayManagerService 代碼中,
代碼的架構如下,IdmapManager是生成對應的映射表。

  • <pre>
  •     Android framework
    
  •        |         ^
    
  •  . . . | . . . . | . . . . 
  • . | | . 
  • .    AIDL,   broadcasts  .
    
  • .   intents      |       .
    
  • . | | . . . . . . . . . . . . 
  • .      v         |       .                     .
    
  • .  OverlayManagerService . OverlayManagerTests .
    
  • .                  \     .     /               .
    
  • . (1)               \    .    /            (3) .
    
  •  . . . . . . . . . . \ . . . / . . . . . . . . .
    
  • .                     \     /              .
    
  • . (2)                  \   /               .
    
  • .           OverlayManagerServiceImpl      .
    
  • . | | . 
  • . | | . 
  • . OverlayManagerSettings     IdmapManager  .
    
  • .                                          .
    
  • . . . .  . . . . . . . . . . . . . . . . . .
    
  • </pre>

通過 adb shell dumpsys overlay 命令可以查看系統里面的overlay包以及包的狀態。

下面命令可以設置每個資源包的狀態,設置成enable就會立即生效,(具體命令可以到代碼里面查到shellcommand)
adb exec-out cmd overlay enable com.android.systemui.theme.dark

實現方法,把新主題的資源和目標apk的資源完全一致的ID,生成一套應用的資源,
<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">RRODemo</string> <string name="hello_world">這是原生應用的資源</string></resources>
overlay資源:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="hello_world">這是rro加載的資源</string></resources>
這里需要替換的就是hello_world的顯示內容,這個名字必須和待替換的資源名(hello_world)相同

manifest按照如下方式實現:

<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>

注意這個apk需要在大環境里面編譯,編譯的mk按照如下方式編寫,注意簽名。
LOCAL_PATH:= (call my-dir) include(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里面。 就可以了。



作者:refactorMe
鏈接:https://www.jianshu.com/p/86720746f135
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

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



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