既然將 Car UI 庫組件和資源放入應用程序中,為了自定義這些應用程序,OEM 必須提供兩個疊加層:
構建時覆蓋。這是覆蓋將添加 RRO 所需的任何資源。這包括:
- 可繪製對象
- 樣式(例如,文本外觀)
共享資源(例如顏色)
RRO 覆蓋。此文件夾包含用於為每個目標應用程序生成一個 RRO 的資源。這些資源只能參考:
- 在同一 RRO 中定義的值(例如,對於顏色,這將是一個十六進制值)。
- Android 框架資源(例如,@android
@android:color/accent
)。 - 在上述構建時覆蓋中定義的資源。
一般結構
建議的定制覆蓋結構如下:
<path-to-OEM-overlays>/
overlay/framework/base/core/res/
。構建時覆蓋資源rro/
Android.mk
。 Makefile 用於根據此文件夾中包含的資源為每個目標包生成 RRO。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
對於所有其他人 (非公共或通過構建時覆蓋添加的資源),使用
*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 限制:
- 使用構建時覆蓋擴展框架/基礎,添加任何必要的資源。
- 使用
*android:
命名空間參考來自 OEM RRO 的這些資源。
例如,以下是添加 OEM 特定可繪製對象並在 RRO 中使用它的方法:
<path-to-OEM-overlays>
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 都是靜態啟用的,並且一次只有一個處於活動狀態。
將汽車 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 \ ...
導致
<path-to-OEM-overlays>/rro/Android.mk
為CAR_UI_RRO_PACKAGE_NAMES
中命名的每個包生成一個 RRO。在
PRODUCT_PACKAGES
中包含生成的 RRO。在
PRODUCT_PACKAGE_OVERLAYS
中包含構建時覆蓋以添加 OEM 特定資源。
要了解哪些包支持car-ui-lib
,請參閱car-ui-lib 支持的包。