عیب‌یابی کردن رونهادهای منبع زمان اجرا

از این محتوا برای عیب‌یابی دلیل اینکه چرا رونهاد منبع زمان اجرا (RRO) ممکن است در پیاده‌سازی Android Automotive عملکرد موردانتظار را نداشته باشد استفاده کنید.

برای کسب اطلاعات بیشتر درباره RRO در Android، به تغییر مقدار منابع برنامه در زمان اجرا مراجعه کنید. حتماً مراقب خروجی logcat باشید، زیرا می‌تواند اطلاعات خوبی درباره آنچه درطول فرایند اتفاق می‌افتد ارائه دهد.

مرحله ۱: فهرست کردن هم‌پوشانی‌های منبع زمان اجرا

برای فهرست کردن RROها:

  1. فرمان زیر را اجرا کنید:

    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
    
  2. تأیید کنید که «سازمان گزارش‌دهنده مسئول» شما در فهرست نشان داده می‌شود. نشانگرهای زیر وضعیت RRO را نشان می‌دهند:

    نشانگر وضعیت هم‌پوشانی منبع زمان اجرا
    [ ] نصب شده و آماده فعال‌سازی است.
    [X] نصب و فعال شد.
    --- نصب شده است اما خطا دارد.

    اگر «هم‌پوشانی منبع زمان اجرا» شما در زیر نام بسته هدفی که می‌خواهید هم‌پوشانی کنید فهرست نشده است، «هم‌پوشانی منبع زمان اجرا» شما نصب نشده است.

مرحله ۲: فعال و غیرفعال کردن RRO

اگر RRO نصب شده باشد:

  1. از فرمان زیر برای فعال (یا غیرفعال) کردن RRO استفاده کنید:

    adb shell cmd overlay [enable/disable] --user current [your RRO package name]

مرحله ۳: تأیید کنید که RRO نصب شده است

برای تأیید اینکه «هم‌پوشانی منبع زمان اجرا» در دستگاه نصب شده است یا عیب‌یابی اینکه چرا «هم‌پوشانی منبع زمان اجرا» فعال نشده است:

  1. فرمان زیر را اجرا کنید:

    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
    }
    
  2. کاربر (یا کاربرانی) را که RRO را نصب کرده است شناسایی کنید. در مثال قبلی، «هم‌پوشانی منبع زمان اجرا» برای کاربر 0 و کاربر 10 دردسترس است (مقادیر mUserId را در بلوک کد بالا ببینید).

  3. برای فعال کردن (یا غیرفعال کردن) RRO برای کاربر، به «مرحله ۲» بروید.

  4. برای بررسی مقدار mState:

    • STATE_ENABLED و STATE_ENABLED_IMMUTABLE. «کنترل از دور» فعال است و برای هدف شما اعمال می‌شود.

    • STATE_MISSING_TARGET. هدف شما نصب نشده است.

    • STATE_NO_IDMAP. مشکلی در نحوه تنظیم فایل‌های AndroidManifest.xml، overlays.xml، یا overlayable.xml وجود دارد. برای اجرای گزارش‌ها و جستجوی کلیدواژه idmap برای شناسایی خطا، از adb logcat استفاده کنید. مراحل ۴ و ۵ را ببینید.

    • ‫STATE_UNKNOWN. مشکلی در OverlayManagerService وجود دارد.

مرحله ۴: بررسی AndroidManifest.xml

برای به‌تأیید رساندن AndroidManifest.xml:

  1. targetName و targetPackage را بررسی کنید.

    ‫android:targetName باید مقدار گروه رونهادپذیر تعریف‌شده در برنامه هدف را داشته باشد. این مورد فقط هنگام هدف‌یابی رونهاد الزامی است.

    ‫android:targetPackage همیشه الزامی است و باید حاوی نام بسته برنامه هدف باشد.

  2. بررسی کنید که RRO شما ثابت است (یا نیست). «پوشش‌های منبع ثابت» به‌طور پیش‌فرض در زمان راه‌اندازی فعال هستند. «پوشش‌های منبع پویا» به‌طور پیش‌فرض در زمان راه‌اندازی فعال نمی‌شوند. روش‌های دیگری برای فعال کردن RROهای پویا در تغییر مقدار منابع برنامه در زمان اجرا ارائه شده است.

  3. اولویت «پوشش منبع قابل‌جایگزینی» (RRO) ایستا را بررسی کنید (اولویت RRO پویا همیشه روی Integer.MAX_VALUE تنظیم می‌شود و ترتیب اعمال آن‌ها براساس زمان فعال شدنشان است).

    چندین «هم‌پوشانی منبع زمان اجرا» می‌تواند برای یک هدف اعمال شود. هم‌پوشانی‌های منبع زمان اجرا با اولویت بالاتر در آخر اعمال می‌شوند. در مقیاس ۰ تا ۱۰، ۱۰ بالاترین و ۰ پایین‌ترین است.

مرحله ۵: بررسی overlays.xml

  1. overlays.xml را علامت بزنید تا تأیید کنید همه منابعی که قصد دارید رونهاد کنید در این فایل تعریف شده‌اند. برای مثال، موارد زیر را درنظر بگیریدoverlays.xml:

    <overlay>
        <item target="string/app_name" value="@string/overlaid_app_name" />
    </overlay>
    
  2. باید مطمئن شوید که:

    • ‫string منبع با نام app_name در برنامه مقصد وجود دارد.
    • ‫string منبع با نام overlaid_app_name در RRO شما وجود دارد.
  3. اگر هدف شما فایل overlayable.xml دارد، مطمئن شوید که app_name در آن فایل موجود باشد. مطمئن شوید که از targetName صحیح در فایل AndroidManifest.xml خود استفاده کنید (مرحله ۴).

    برای مثال:

    <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>
    

مرحله ۶: تخلیه idmap

در این مرحله، همه مشکلات مربوط به «درخواست برداشتن محتوا» شما باید برطرف شده باشد. سپس، idmap RRO خود را تخلیه کنید تا ببینید منبع چگونه حل می‌شود و چرا به مقداری متفاوت از آنچه انتظار دارید حل می‌شود.

  1. برای پیدا کردن مسیر idmap در دستگاهتان:

    adb shell
    su
    ls data/resource-cache
  2. برای تخلیه محتوای آن فایل:

    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 شما به کدام شناسه در هدف شما و همچنین نام منبع رونهادشده نگاشت شده است.

    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!!")

عدم موفقیت در حل نگاشت‌ها با idmap2 ازطریق سه علامت سؤال (???) نشان داده می‌شود.

در این مثال، «هم‌پوشانی منبع زمان اجرا» دارای مقدار رنگ کدگذاری‌شده‌ای است که روی منبعی عمومی هم‌پوشانی شده است:

$ idmap2 dump --idmap-path [file]
0x00010402 -> color 0xff00ff00 (???)

در این مثال، RRO با اشاره کردن به منبع رنگ داخلی (خصوصی) در همان کتابخانه هم‌رسانی‌شده، منبع عمومی را رونهاد می‌کند:

$ idmap2 dump --idmap-path [file]
0x00010402 -> 0x7f010000 (??? -> color/item_background_new)