이 콘텐츠를 사용하여 런타임 리소스 오버레이(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 확인하기
이 단계는 Android 11 이상에만 적용됩니다.
- overlays.xml을 확인하여 오버레이하려는 모든 리소스가 이 파일에 정의되어 있는지 검토합니다. 예를 들어, 다음- overlays.xml을 고려해 보세요.- <overlay> <item target="string/app_name" value="@string/overlaid_app_name" /> </overlay>
- 다음과 같아야 합니다. - 이름이 app_name인string리소스가 타겟 앱에 있습니다.
- 이름이 overlaid_app_name인string리소스가 RRO에 있습니다.
 
- 이름이 
- 타겟에 - 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
- 이 파일의 콘텐츠를 덤프하는 방법은 다음과 같습니다. - idmap2 dump --idmap-path [path to your RRO idmap file]- 출력은 다음과 같이 표시됩니다. 출력에는 오버레이된 리소스 이름과 함께 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!!")