• 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
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    SVN:多版本库环境的搭建
    记一次KUBERNETES/DOCKER网络排障
    k8s部署prometheus
    误删除 linux 系统文件了?这个方法教你解决
    kubectl命令自动补全
    git杂记:忽略ssl认证
    微软官方原版本下载msdn
    Android Studio 小技巧(2):AS中Button文字默认大写的问题
    <Android 基础(十一)> Snackbar
    <Android 基础(十)> FloatingActionButton
  • 原文地址:https://www.cnblogs.com/xgjblog/p/14805562.html
Copyright © 2020-2023  润新知