您可以参考本文的内容,找出运行时资源叠加层 (RRO) 在 Android Automotive 实现中可能无法正常运行的原因。
相关文档
如需详细了解 Android 中的 RRO,请参阅在运行时更改应用资源的值。
请务必时时注意 logcat 输出,该输出可提供有关整个过程中所发生情况的有用信息。
第 1 步:列出 RRO
如需列出 RRO,请执行以下操作:
- 运行以下命令: - adb shell cmd overlay list --user current- 系统会显示类似如下文本的输出: - com.android.systemui [ ] com.android.theme.icon_pack.rounded.systemui [ ] com.android.theme.icon_pack.filled.systemui [ ] com.android.theme.icon_pack.circular.systemui com.android.permissioncontroller --- com.android.permissioncontroller.googlecarui.rro
- 验证您的 RRO 是否显示在列表中。以下指标可指明 RRO 状态: - 指标 - RRO 状态 - [ ]- 已安装,待激活。 - [X]- 已安装,已激活。 - ---- 已安装,但包含错误。 - 如果相应 RRO 未在叠加目标的软件包名称下方列出,则表明该 RRO 尚未安装。 
第 2 步:启用和停用 RRO
如果已安装 RRO,请执行以下操作:
- 使用以下命令启用(或停用)RRO: - adb shell cmd overlay [enable/disable] --user current [your RRO package name]
第 3 步:确认是否已安装 RRO
如需确认设备上是否已安装某个 RRO,或要找出该 RRO 未启用的原因,请执行以下操作:
- 运行以下命令: - adb shell cmd overlay dump [your RRO package name]- 会显示如下输出: - com.android.car.rotaryplayground.googlecarui.rro:0 { mPackageName...........: com.android.car.rotaryplayground.googlecarui.rro mUserId................: 0 mTargetPackageName.....: com.android.car.rotaryplayground mTargetOverlayableName.: car-ui-lib mBaseCodePath..........: /product/overlay/googlecarui-com-android-car-rotaryplayground/googlecarui-com-android-car-rotaryplayground.apk mState.................: STATE_MISSING_TARGET mIsEnabled.............: true mIsMutable.............: true mPriority..............: 10 mCategory..............: BypassIdMapV1 } com.android.car.rotaryplayground.googlecarui.rro:10 { mPackageName...........: com.android.car.rotaryplayground.googlecarui.rro mUserId................: 10 mTargetPackageName.....: com.android.car.rotaryplayground mTargetOverlayableName.: car-ui-lib mBaseCodePath..........: /product/overlay/googlecarui-com-android-car-rotaryplayground/googlecarui-com-android-car-rotaryplayground.apk mState.................: STATE_MISSING_TARGET mIsEnabled.............: true mIsMutable.............: true mPriority..............: 10 mCategory..............: BypassIdMapV1 }
- 确定已安装该 RRO 的用户。在上面的示例中,该 RRO 适用于用户 - 0和用户- 10(请参见顶部代码块中- mUserId的值)。
- 如需为用户启用(或停用)该 RRO,请转到第 2 步。 
- 如需查看 - mState的值,请执行以下操作:- STATE_ENABLED和- STATE_ENABLED_IMMUTABLE。RRO 已启用,并已应用于您的目标。
- STATE_MISSING_TARGET。您的目标尚未安装。
- STATE_NO_IDMAP。- AndroidManifest.xml、- overlays.xml或- overlayable.xml文件的设置方式存在问题。您可以使用- adb logcat运行日志,并搜索关键字“- idmap”,找出错误所在。请参阅第 4 步和第 5 步。
- STATE_UNKNOWN。- OverlayManagerService出现了问题。
 
第 4 步:检查 AndroidManifest.xml
为验证 AndroidManifest.xml,请执行以下操作:
- 检查 - targetName和- targetPackage。- android:targetName的值应与目标应用中定义的可叠加组的值相同。只有在定位叠加层时,才需满足此要求。- android:targetPackage始终是必需项,并且应包含目标应用的软件包名称。
- 检查您的 RRO 是否处于静态。默认情况下,系统在启动时会启用静态 RRO。默认情况下,系统在启动时不会启用动态 RRO。在运行时更改应用资源的值中提供了启用动态 RRO 的其他方法。 
- 检查静态 RRO 的优先级(动态 RRO 的优先级始终设为 - Integer.MAX_VALUE,并且它们的应用顺序取决于它们的启用时间)。- 可以为同一目标应用多个 RRO。RRO 的优先级越高,应用顺序越靠后。优先级范围为 0 到 10,其中 10 代表最高,0 代表最低。 
第 5 步:检查 overlays.xml
- 请检查 - overlays.xml,确认该文件中是否已定义您要叠加的所有资源。例如,请考虑以下- overlays.xml:- <overlay> <item target="string/app_name" value="@string/overlaid_app_name" /> </overlay>
- 您必须确保: - 目标应用中存在名为 app_name的string资源。
- 您的 RRO 中存在名为 overlaid_app_name的string资源。
 
- 目标应用中存在名为 
- 如果您的目标包含 - overlayable.xml文件,请确保该文件中包含- app_name。请务必在- AndroidManifest.xml文件中使用正确的- targetName(第 4 步)。- 例如: - <overlay> <item target="layout/car_ui_base_layout_toolbar" value="@layout/car_ui_base_layout_toolbar" /> <item target="id/car_ui_toolbar_background" value="@id/car_ui_toolbar_background" /> <item target="attr/layout_constraintTop_toBottomOf" value="@attr/layout_constraintTop_toBottomOf" /> </overlay>
第 6 步:转储 idmap
在此阶段,RRO 的所有问题都应已解决。接下来,转储 RRO 的 idmap,以了解资源的解析情况;如果资源解析值与您的预期不同,您还可以从中了解原因。
- 如需在设备上查找 - idmap所在的路径,请执行以下操作:- adb shell su ls data/resource-cache
- 如需转储该文件的内容,请执行以下操作: - adb root adb shell idmap2 dump --idmap-path [path to your RRO idmap file]- 示例: - adb shell idmap2 dump --idmap-path data/resource-cache/system@app@CarUiPortraitLauncherReferenceRRO@CarUiPortraitLauncherReferenceRRO.apk@idmap- 输出的内容应类似于如下文本。输出会显示 RRO 中的各个 ID 与目标中的具体 ID 之间的映射对应关系,以及叠加资源的名称。 - target apk path : /system/priv-app/CarMediaApp/CarMediaApp.apk overlay apk path : /product/overlay/googlecarui-com-android-car-media/googlecarui-com-android-car-media.apk 0x7f040008 -> 0x7f010000 bool/car_ui_toolbar_logo_fills_nav_icon_space 0x7f040009 -> 0x7f010001 bool/car_ui_toolbar_nav_icon_reserve_space 0x7f04000b -> 0x7f010002 bool/car_ui_toolbar_tab_flexible_layout 0x7f04000c -> 0x7f010003 bool/car_ui_toolbar_tabs_on_second_row 0x7f09006c -> 0x7f020000 id/car_ui_base_layout_content_container 0x7f090073 -> 0x7f020001 id/car_ui_recycler_view 0x7f090074 -> 0x7f020002 id/car_ui_scroll_bar 0x7f090075 -> 0x7f020003 id/car_ui_scrollbar_page_down 0x7f090076 -> 0x7f020004 id/car_ui_scrollbar_page_up 0x7f090077 -> 0x7f020005 id/car_ui_scrollbar_thumb 0x7f090078 -> 0x7f020006 id/car_ui_scrollbar_track 0x7f09007a -> 0x7f020007 id/car_ui_toolbar_background 0x7f09007e -> 0x7f020008 id/car_ui_toolbar_logo 0x7f090084 -> 0x7f020009 id/car_ui_toolbar_menu_items_container 0x7f090085 -> 0x7f02000a id/car_ui_toolbar_nav_icon 0x7f090086 -> 0x7f02000b id/car_ui_toolbar_nav_icon_container 0x7f090087 -> 0x7f02000c id/car_ui_toolbar_progress_bar 0x7f090089 -> 0x7f02000d id/car_ui_toolbar_row_separator_guideline 0x7f09008d -> 0x7f02000e id/car_ui_toolbar_search_view_container 0x7f09008f -> 0x7f02000f id/car_ui_toolbar_subtitle 0x7f090092 -> 0x7f020010 id/car_ui_toolbar_tabs 0x7f090093 -> 0x7f020011 id/car_ui_toolbar_title 0x7f090094 -> 0x7f020012 id/car_ui_toolbar_title_container 0x7f090095 -> 0x7f020013 id/car_ui_toolbar_title_logo 0x7f090096 -> 0x7f020014 id/car_ui_toolbar_title_logo_container 0x7f0c0024 -> 0x7f030000 layout/car_ui_base_layout_toolbar 0x7f0c0035 -> 0x7f030001 layout/car_ui_recycler_view 0x7f0c0038 -> 0x7f030002 layout/car_ui_toolbar 0x7f0c003f -> 0x7f030003 layout/car_ui_toolbar_two_row
使用以下命令查找特定资源,了解它们的映射方式:
adb shell cmd overlay lookup --verbose --user 10 com.android.car.ui.paintbooth com.android.car.ui.paintbooth:color/widget_background输出内容是资源的最终值:
#ff7986cb
您还可以从 APK 转储布局文件,从而查看解析的 ID,其解析结果应与上方的输出一致:
aapt2 dump xmltree $OUT/system/priv-app/sharedlibraryclient/sharedlibraryclient.apk --file res/layout/activity_main.xml系统会返回类似如下文本的输出:
N: android=http://schemas.android.com/apk/res/android (line=2)
  N: app=http://schemas.android.com/apk/res-auto (line=2)
    N: lib=http://schemas.android.com/apk/com.android.car.ui.sharedlibrary.test (line=2)
      E: androidx.constraintlayout.widget.ConstraintLayout (line=2)
        A: http://schemas.android.com/apk/res/android:layout_width(0x010100f4)=-1
        A: http://schemas.android.com/apk/res/android:layout_height(0x010100f5)=-1
          E: TextView (line=19)
            A: http://schemas.android.com/apk/res/android:layout_width(0x010100f4)=-2
            A: http://schemas.android.com/apk/res/android:layout_height(0x010100f5)=-2
            A: http://schemas.android.com/apk/res/android:text(0x0101014f)=@0x020f0000
            A: http://schemas.android.com/apk/res-auto:layout_constraintBottom_toBottomOf(0x7f0200fb)=0
            A: http://schemas.android.com/apk/res-auto:layout_constraintLeft_toLeftOf(0x7f02010e)=0
            A: http://schemas.android.com/apk/res-auto:layout_constraintRight_toRightOf(0x7f020112)=0
            A: http://schemas.android.com/apk/res-auto:layout_constraintTop_toTopOf(0x7f020118)=0
          E: com.android.car.ui.sharedlibrary.test.MyRecyclerView (line=28)
            A: http://schemas.android.com/apk/res/android:layout_width(0x010100f4)=-2
            A: http://schemas.android.com/apk/res/android:layout_height(0x010100f5)=-2
            A: http://schemas.android.com/apk/com.android.car.ui.sharedlibrary.test:implClass="HelloWorld!" (Raw: "HelloWorld!")
          E: com.android.car.ui.sharedlibraryclient.CustomView (line=34)
            A: http://schemas.android.com/apk/res/android:layout_width(0x010100f4)=-2
            A: http://schemas.android.com/apk/res/android:layout_height(0x010100f5)=-2
            A: http://schemas.android.com/apk/res-auto:implClass2(0x7f0200e8)="HelloWorld!!" (Raw: "HelloWorld!!")
无法解析映射时,idmap2 会通过三个问号 (???) 指示。
在此示例中,RRO 在公共资源上叠加了硬编码的颜色值:
$ idmap2 dump --idmap-path [file]
0x00010402 -> color 0xff00ff00 (???)在此示例中,RRO 通过将公共资源指向同一共享库中的内部(私有)颜色资源来叠加该公共资源:
$ idmap2 dump --idmap-path [file]
0x00010402 -> 0x7f010000 (??? -> color/item_background_new)