既然 Car UI 库组件和资源已放入应用,为了自定义这些应用,OEM 必须提供两个叠加层
-
构建时叠加层添加运行时资源叠加层 (RRO) 所需的任何资源。其中包括:
- 可绘制对象
- 样式(例如,文本外观)
- 共享资源(例如,颜色)
-
RRO 叠加层文件夹包含用于为每个目标应用生成一个 RRO 的资源。这些资源只能引用:
- 在同一 RRO 中定义的值(例如,对于颜色,这将是十六进制值)。
- Android 框架资源(例如,
@android:color/accent
)。 - 在上述构建时叠加层中定义的资源。
常规结构
建议的自定义叠加层结构如下:
-
<OEM 叠加层路径>/
-
overlay/framework/base/core/res/
。构建时叠加层资源 -
rro/
-
Android.mk
。用于根据此文件夹中包含的资源为每个目标软件包生成 RRO 的 Makefile。 -
AndroidManifest.xml
。上述 Makefile 使用的清单文件模板。 -
res/
。应用于所有目标应用的运行时叠加层。
-
-
OEM 可能有多个此类结构,具体取决于他们想要在单个构建目标中处理的品牌数量(请参阅处理多个品牌)。
运行时资源叠加层
OEM 叠加层文件夹中的 RRO 文件夹应包含要应用于所有目标应用的资源。RRO 对其叠加复合资源的能力有限制。总而言之,RRO:
-
不能引用在目标 APK 或 RRO 本身中定义的资源标识符。这意味着 RRO 无法添加新的标识符,例如新的可绘制对象、颜色或样式。
-
可以 引用在框架中定义的资源标识符,无论这些资源是在
/frameworks/base/core/res
中定义的,还是通过构建时叠加层定义的。这些标识符必须使用android:
命名空间引用。-
对于公开 DeviceDefault RRO,请使用
android
。
例如,@android:style/TextAppearance.DeviceDefault.Large
。 -
对于所有其他 RRO(非公开资源或通过构建时叠加层添加的资源),请使用
*android
。
例如,@*android/style:TextAppearance.OEM.Brand1.Title
。
-
除了资源之外,RRO 文件夹还必须包含:
-
AndroidManifest.xml
。在下面的示例中,RRO_PACKAGE_NAME
和TARGET_PACKAGE_NAME
是 makefile 的占位符<?xml version=“1.0” encoding=“utf-8”?> <manifest xmlns:android=“http://schemas.android.com/apk/res/android” package=“{{RRO_PACKAGE_NAME}}” /> <application android:hasCode=“false” /> <overlay android:priority=“10” android:targetPackage=“{{TARGET_PACKAGE_NAME}}” android:requiredSystemPropertyName=“ro.product.sku” android:requiredSystemPropertyValue=“<your-product-sku>” /> </manifest>
Android.mk
,其中以下 makefile 中的oem
定义了所有生成的 RRO 都将具有的前缀。LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) CAR_UI_RRO_SET_NAME := oem CAR_UI_RESOURCE_DIR := $(LOCAL_PATH)/res CAR_UI_RRO_TARGETS := $(CAR_UI_RRO_PACKAGE_NAMES) include packages/apps/Car/libs/car-ui-lib/generate_rros.mk
配置 RRO
支持新的配置文件 overlayable.xml
,您可以使用它来定义访问控制。例如,您可以指定谁可以叠加资源以及可以叠加哪些资源。因此,现在可以以不同的方式对资源进行分组,使其可供不同的 RRO 叠加。
要设置 RRO 访问控制:
- 在
res/values
文件夹中,创建overlayable.xml
。 - 创建
<overlayable>
资源标记。 - 为
<overlayable>
标记定义name
属性,该属性在软件包中必须是唯一的。每个叠加层只能以一个可叠加组为目标。 - 在
<overlayable>
内定义<policy>
标记。 - 定义可以叠加的资源组。例如:
<resources> <overlayable name="OverlayableResources"> <policy type="public"> <item type="string" name="app_title" /> </policy> </overlayable> </resources>
要将以下更改应用于您的 RRO 项目:
- 在
res/xml
文件夹中,创建overlays.xml
。请参阅以下代码示例中overlay
的条目。 - 定义要替换的资源。
- 将
android:resourcesMap="@xml/overlays"
添加到AndroidManifest.xml
中的<overlay>
标记。例如,在以下代码示例中,请参阅<overlay>
的条目。 - 为静态叠加层设置
android:isStatic=”true”
。每个叠加层只能以可以叠加的组中的一个为目标。
考虑以下示例。第一部分属于 AndroidManifest.xml
,而第二部分属于 overlays.xml
。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.car.ui.rro" android:versionCode="1" android:versionName="1.0"> <overlay android:targetName="OverlayableResources" android:resourcesMap="@xml/overlays" android:targetPackage="com.android.car.ui" android:priority="1" android:isStatic="false" /> </manifest> <overlay> <item target="string/app_title" value="@ string/app_title" /> </overlay>
有一个例外,以前存在的 RRO 在 Android 10 中可以正常工作。例外情况是,要通过 PackageManagerRRO 安装,软件包必须是预安装的,或者使用与目标应用相同的密钥签名。在 Android 10 中,可以叠加布局文件。但是,这样做需要在获取视图时使用 requireViewById()
而不是 findViewById()
。在 Android 10 中,此更改已在 car-ui-lib 中实现,以支持布局叠加层。
下一个 Android 主要版本将使您能够叠加布局文件,并在 RRO 软件包中定义新资源并在内部引用它们。
添加 OEM 特定的资源
为了克服阻止添加 OEM 资源的 RRO 限制:
- 使用构建时叠加层扩展 frameworks/base,添加任何必要的资源。
- 使用
*android:
命名空间从 OEM RRO 引用这些资源。
例如,以下是添加 OEM 特定可绘制对象并在 RRO 中使用它的方法:
-
<OEM 叠加层路径>
-
overlay/framework/base/core/res/res/drawable/
-
oem_background_drawable.xml
-
-
rro/res/values
-
drawables.xml
<resources> <item type="drawable" name="car_ui_toolbar_background"> @*android:drawable/oem_background_drawable </item> </resources>
-
-
处理多个品牌
RRO 清单文件具有语法,允许根据系统属性有条件地应用它们。要在单个系统映像中处理多个品牌,OEM 可以按如下方式使用它(请参阅常规结构)。
<?xml version=“1.0” encoding=“utf-8”?> <manifest xmlns:android=“http://schemas.android.com/apk/res/android” package=“{{RRO_PACKAGE_NAME}}”/> <application android:hasCode=“false”/> <overlay android:priority=“10” android:targetPackage=“{{TARGET_PACKAGE_NAME}}” android:requiredSystemPropertyName=“ro.product.sku” android:requiredSystemPropertyValue=“<your-product-sku>”/> </manifest>
android:requiredSystemPropertyName
和 android:requiredSystemPropertyValue
的语法将导致仅当相应的系统属性与提供的值匹配时才启用此 RRO。然后,OEM 可以定义多个这些 RRO,所有这些 RRO 都是静态启用的,并且一次只有一个处于活动状态。
将 Car UI 库添加到目标
要将 Car UI 库合并到 Android 目标中,您必须包含以下代码段:
# Include build-time overlays PRODUCT_PACKAGE_OVERLAYS += \ <path-to-oem-overlays>/overlay # Define package names to generate RROs for CAR_UI_RRO_PACKAGE_NAMES += \ com.android.car.ui.paintbooth \ com.android.car.media \ com.android.car.dialer \ com.android.car.linkviewer \ com.android.car.settings \ com.android.car.systemupdater \ com.google.android.apps.automotive.inputmethod \ com.google.android.apps.automotive.templates.host \ ... # Include generated RROs PRODUCT_PACKAGES += \ oem-com-android-car-ui-paintbooth \ oem-com-android-car-media \ oem-com-android-car-dialer \ oem-com-android-car-linkviewer \ oem-com-android-car-settings \ oem-com-android-car-systemupdater \ oem-com-google-android-apps-automotive-inputmethod \ oem-com-google-android-apps-automotive-templates-host \ ...
-
使
<OEM 叠加层路径>/rro/Android.mk
为CAR_UI_RRO_PACKAGE_NAMES
中命名的每个软件包生成一个 RRO。 -
将生成的 RRO 包含在
PRODUCT_PACKAGES
中。 -
在
PRODUCT_PACKAGE_OVERLAYS
中包含构建时叠加层以添加 OEM 特定的资源。
要了解哪些软件包支持 car-ui-lib
,请参阅包含 car-ui-lib 的软件包列表。