android动态主题切换(RRO 技术)

android上的主题切换,Android从M开始加入了动态资源overlay机制 runtime resource overlay(RRO),这个是sony贡献的,实现机制如下图,就是在框架中建立一套资源ID映射表,通过这个映射表动态切换不同的主题。

image.png

具体的代码实现在 OverlayManagerService 代码中,
代码的架构如下,IdmapManager是生成对应的映射表。

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

通过 adb shell dumpsys overlay 命令可以查看系统里面的overlay包以及包的状态。

下面命令可以设置每个资源包的状态,设置成enable就会立即生效,(具体命令可以到代码里面查到shellcommand)
adb exec-out cmd overlay enable com.android.systemui.theme.dark

实现方法,把新主题的资源和目标apk的资源完全一致的ID,生成一套应用的资源,
RRODemo 这是原生应用的资源
overlay资源:
这是rro加载的资源
这里需要替换的就是hello_world的显示内容,这个名字必须和待替换的资源名(hello_world)相同

manifest按照如下方式实现:

package="com.android.systemui.theme.dark"
android:versionCode="1"
android:versionName="1.0">


注意这个apk需要在大环境里面编译,编译的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里面。 就可以了。

你可能感兴趣的:(android动态主题切换(RRO 技术))