ใช้เนื้อหานี้เพื่อแก้ปัญหาสาเหตุที่รันไทม์ทรัพยากรซ้อนทับ (RRO) อาจ ไม่ทำงานตามที่คาดหวังในการใช้งาน Android Automotive
เอกสารประกอบที่เกี่ยวข้อง
ดูข้อมูลเพิ่มเติมเกี่ยวกับ RRO ใน Android ได้ที่
เปลี่ยนค่าทรัพยากรของแอปขณะรันไทม์
อย่าลืมติดตามเอาต์พุตของ 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 และ 5STATE_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: ตรวจสอบOverlay.xml
การตรวจสอบนี้มีผลกับ Android 11 (และสูงกว่า) เท่านั้น
เลือก
overlays.xml
เพื่อยืนยันว่าทรัพยากรทั้งหมดที่คุณต้องการวางซ้อนอยู่ กำหนดไว้ในไฟล์นี้ ลองดูตัวอย่างต่อไปนี้overlays.xml
<overlay> <item target="string/app_name" value="@string/overlaid_app_name" /> </overlay>
โดยคุณต้องตรวจสอบว่า
- มีทรัพยากร
string
ที่ใช้ชื่อapp_name
ในแอปเป้าหมายแล้ว - มีทรัพยากร
string
ที่ใช้ชื่อoverlaid_app_name
อยู่ใน RRO ของคุณแล้ว
- มีทรัพยากร
หากเป้าหมายมีไฟล์
overlayable.xml
ให้ตรวจสอบว่าapp_name
เป็น ที่มีอยู่ในไฟล์นั้น โปรดตรวจสอบว่าคุณใช้targetName
ที่ถูกต้องในAndroidManifest.xml
(ขั้นตอนที่ 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: ดัมพ์ ID แมป
ในขั้นตอนนี้ ปัญหาทั้งหมดเกี่ยวกับ 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]
ตัวอย่าง
posix-terminal adb shell idmap2 dump --idmap-path data/resource-cache/system@app@CarUiPortraitLauncherReferenceRRO@CarUiPortraitLauncherReferenceRRO.apk@idmap
เอาต์พุตจะมีลักษณะคล้ายกับตัวอย่างด้านล่างนี้ เอาต์พุตจะแสดงรหัส จาก RRO จะถูกแมปกับรหัสในเป้าหมายของคุณและชื่อของ ทรัพยากรที่วางซ้อน
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 เพื่อดูรหัสที่แก้ไขแล้วได้ด้วย เพื่อให้ตรงกับเอาต์พุตข้างต้น
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!!")