تصحيح أخطاء الملفات الشخصية المرجعية

يقدّم هذا المستند أفضل الممارسات وخطوات تحديد المشاكل وحلّها للمساعدة في تشخيص المشاكل والتأكّد من أنّ "ملفات تعريف الخط الأساس" تعمل بشكل صحيح لتحقيق أكبر فائدة.

مشاكل في الإنشاء

إذا نسخت مثال "ملفات Baseline" في تطبيق Now in Android التجريبي، قد تواجه حالات تعذُّر الاختبار أثناء مهمة "ملف Baseline"، مع الإشارة إلى أنّه لا يمكن إجراء الاختبارات على محاكي:

./gradlew assembleDemoRelease
Starting a Gradle Daemon (subsequent builds will be faster)
Calculating task graph as no configuration cache is available for tasks: assembleDemoRelease
Type-safe project accessors is an incubating feature.

> Task :benchmarks:pixel6Api33DemoNonMinifiedReleaseAndroidTest
Starting 14 tests on pixel6Api33

com.google.samples.apps.nowinandroid.foryou.ScrollForYouFeedBenchmark > scrollFeedCompilationNone[pixel6Api33] FAILED
        java.lang.AssertionError: ERRORS (not suppressed): EMULATOR
        WARNINGS (suppressed):
        ...

تحدث حالات الفشل لأنّ تطبيق "كل جديد في Android" يستخدم جهازًا مُدارًا من Gradle لإنشاء "ملف تعريف Baseline". من المتوقّع حدوث حالات فشل، لأنّه لا يُنصح بشكل عام بتشغيل مقاييس أداء على محاكي. ومع ذلك، بما أنّك لا تجمع مقاييس الأداء عند إنشاء ملفات Baseline Profile، يمكنك تشغيل عملية جمع ملفات Baseline Profile على المحاكيات لتسهيل الأمر. لاستخدام "ملفات Baseline" مع محاكي، عليك إنشاء التطبيق وتثبيته من سطر الأوامر، وتحديد وسيطة لتفعيل قواعد "ملفات Baseline":

installDemoRelease -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile

بدلاً من ذلك، يمكنك إنشاء إعداد تشغيل مخصّص في "استوديو Android" لتفعيل "ملفات Baseline" على المحاكيات من خلال اختيار تشغيل > تعديل الإعدادات:

إضافة إعداد تشغيل مخصّص لإنشاء "ملفات Baseline" في تطبيق "أندرويد الآن"
الشكل 1. أضِف إعداد تشغيل مخصّصًا لإنشاء ملفات Baseline Profiles في تطبيق Now in Android.

التحقّق من تثبيت الملف الشخصي وتطبيقه

للتأكّد من أنّ حزمة APK أو حزمة تطبيق Android (AAB) التي تفحصها مأخوذة من صيغة إصدار تتضمّن "ملفات تعريف Baseline"، اتّبِع الخطوات التالية:

  1. في "استوديو Android"، انقر على إنشاء > تحليل حزمة APK.
  2. افتح حزمة AAB أو APK.
  3. تأكَّد من توفّر الملف baseline.prof:

    • إذا كنت تفحص حزمة AAB، سيكون الملف الشخصي في /BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof.
    • إذا كنت تفحص حزمة APK، سيكون الملف الشخصي في /assets/dexopt/baseline.prof.

      يشكّل توفّر هذا الملف أول مؤشر على صحة إعدادات الإصدار. إذا لم يكن متوفّرًا، يعني ذلك أنّ "وقت تشغيل Android" لن يتلقّى أي تعليمات مسبقة بشأن التجميع في وقت التثبيت.

      التحقّق من توفّر "ملف تعريف أساسي" باستخدام "أداة تحليل حِزم APK" في "استوديو Android"
      الشكل 2. ابحث عن "الملف الأساسي" باستخدام "أداة تحليل ملفات APK" في "استوديو Android".

يجب تجميع "ملفات Baseline Profile" على الجهاز الذي يتم تشغيل التطبيق عليه. وعند تثبيت إصدارات غير قابلة للتصحيح باستخدام "استوديو Android" أو أداة سطر الأوامر الخاصة ببرنامج Gradle المغلّف، تتم عملية التجميع على الجهاز تلقائيًا. في حال تثبيت التطبيق من "متجر Google Play"، يتم تجميع "ملفات تعريف خط الأساس" أثناء تحديثات الجهاز في الخلفية بدلاً من وقت التثبيت. عند تثبيت التطبيق باستخدام أدوات أخرى، تكون مكتبة Jetpack ProfileInstaller مسؤولة عن إضافة الملفات الشخصية إلى قائمة الانتظار لتجميعها أثناء عملية تحسين DEX التالية في الخلفية.

في هذه الحالات، إذا أردت التأكّد من استخدام "ملفات Baseline"، قد تحتاج إلى فرض تجميع "ملفات Baseline". تتيح لك السمة ProfileVerifier طلب البحث عن حالة تثبيت الملف الشخصي وتجميعه، كما هو موضّح في المثال التالي:

Kotlin

private const val TAG = "MainActivity"

class MainActivity : ComponentActivity() {
  ...
  override fun onResume() {
    super.onResume()
    lifecycleScope.launch {
      logCompilationStatus()
    }
  }

  private suspend fun logCompilationStatus() {
     withContext(Dispatchers.IO) {
        val status = ProfileVerifier.getCompilationStatusAsync().await()
        when (status.profileInstallResultCode) {
            RESULT_CODE_NO_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Baseline Profile not found")
            RESULT_CODE_COMPILED_WITH_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Compiled with profile")
            RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING ->
                Log.d(TAG, "ProfileInstaller: App was installed through Play store")
            RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST ->
                Log.d(TAG, "ProfileInstaller: PackageName not found")
            RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ ->
                Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read")
            RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE ->
                Log.d(TAG, "ProfileInstaller: Can't write cache file")
            RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            else ->
                Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued")
        }
    }
}

Java

public class MainActivity extends ComponentActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onResume() {
        super.onResume();

        logCompilationStatus();
    }

    private void logCompilationStatus() {
         ListeningExecutorService service = MoreExecutors.listeningDecorator(
                Executors.newSingleThreadExecutor());
        ListenableFuture<ProfileVerifier.CompilationStatus> future =
                ProfileVerifier.getCompilationStatusAsync();
        Futures.addCallback(future, new FutureCallback<>() {
            @Override
            public void onSuccess(CompilationStatus result) {
                int resultCode = result.getProfileInstallResultCode();
                if (resultCode == RESULT_CODE_NO_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Baseline Profile not found");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Compiled with profile");
                } else if (resultCode == RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING) {
                    Log.d(TAG, "ProfileInstaller: App was installed through Play store");
                } else if (resultCode == RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST) {
                    Log.d(TAG, "ProfileInstaller: PackageName not found");
                } else if (resultCode == RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ) {
                    Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read");
                } else if (resultCode
                        == RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE) {
                    Log.d(TAG, "ProfileInstaller: Can't write cache file");
                } else if (resultCode == RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else {
                    Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued");
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d(TAG,
                        "ProfileInstaller: Error getting installation status: " + t.getMessage());
            }
        }, service);
    }
}

تقدّم رموز النتائج التالية تلميحات حول سبب بعض المشاكل:

RESULT_CODE_COMPILED_WITH_PROFILE
يتم تثبيت الملف الشخصي وتجميعه واستخدامه كلما تم تشغيل التطبيق. هذه هي النتيجة التي تريدها.
RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED
لم يتم العثور على أي ملف شخصي في حزمة APK التي يتم تشغيلها. تأكَّد من أنّك تستخدم صيغة إنشاء تتضمّن ملفات Baseline Profiles إذا ظهر لك هذا الخطأ، ومن أنّ حِزمة APK تحتوي على ملف.
RESULT_CODE_NO_PROFILE
لم يتم تثبيت أي ملف شخصي لهذا التطبيق عند تثبيته من خلال متجر التطبيقات أو مدير الحِزم. السبب الرئيسي لظهور رمز الخطأ هذا هو عدم تشغيل برنامج تثبيت الملف الشخصي بسبب إيقاف ProfileInstallerInitializer. يُرجى العِلم أنّه عند الإبلاغ عن هذا الخطأ، تم العثور على ملف شخصي مضمّن في حزمة APK للتطبيق. عندما يتعذّر العثور على ملف شخصي مضمّن، يكون رمز الخطأ الذي يتم عرضه هو RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED.
RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
يتم العثور على ملف شخصي في حزمة APK أو AAB ويتم وضعه في قائمة الانتظار لتجميعه. عندما يتم تثبيت ملف شخصي بواسطة ProfileInstaller، يتم وضعه في قائمة الانتظار ليتم تجميعه في المرة التالية التي يُجري فيها النظام عملية تحسين DEX في الخلفية. لن يكون الملف الشخصي نشطًا إلا بعد اكتمال عملية التجميع. لا تحاول قياس أداء ملفات Baseline Profiles إلى أن يكتمل التجميع. قد تحتاج إلى فرض تجميع ملفات Baseline Profiles. لن يحدث هذا الخطأ عند تثبيت التطبيق من &quot;متجر Play&quot; أو مدير الحِزم على الأجهزة التي تعمل بالإصدار 9 (المستوى 28 لواجهة برمجة التطبيقات) من نظام التشغيل Android والإصدارات الأحدث، لأنّه يتم إجراء عملية التجميع أثناء التثبيت.
RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING
تم تثبيت ملف تعريف غير متطابق وتم تجميع التطبيق معه. هذا هو نتيجة التثبيت من خلال "متجر Google Play" أو مدير الحِزم. يُرجى العِلم أنّ هذه النتيجة تختلف عن RESULT_CODE_COMPILED_WITH_PROFILE لأنّ الملف الشخصي غير المتطابق لن يجمع سوى أي طرق لا تزال مشترَكة بين الملف الشخصي والتطبيق. وبالتالي، يكون حجم الملف الشخصي أصغر من المتوقّع، وسيتم تجميع عدد أقل من الطرق مقارنةً بما تم تضمينه في "الملف الأساسي".
RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE
يتعذّر على
ProfileVerifier كتابة ملف التخزين المؤقت لنتائج التحقّق. يمكن أن يحدث ذلك إما بسبب مشكلة في أذونات مجلد التطبيق أو بسبب عدم توفّر مساحة فارغة كافية على القرص على الجهاز.
RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION
لا تتوافق
ProfileVerifieris running on an unsupported API version of Android. ProfileVerifier إلا مع الإصدار 9 من نظام التشغيل Android (المستوى 28 من واجهة برمجة التطبيقات) والإصدارات الأحدث.
RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST
يتم عرض PackageManager.NameNotFoundException عند طلب البحث من PackageManager عن حزمة التطبيق. من المفترض أن يحدث ذلك نادرًا. جرِّب إلغاء تثبيت التطبيق وإعادة تثبيت كل شيء.
RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ
يتوفّر ملف ذاكرة تخزين مؤقت لنتيجة إثبات الملكية السابقة، ولكن لا يمكن قراءته. ومن المفترض أن تكون هذه الحالات نادرة. جرِّب إلغاء تثبيت التطبيق وإعادة تثبيت كل شيء.

استخدام ProfileVerifier في الإصدار العلني

في مرحلة الإنتاج، يمكنك استخدام ProfileVerifier مع مكتبات إعداد التقارير الإحصائية، مثل إحصاءات Google لبرنامج Firebase، لإنشاء أحداث إحصائية تشير إلى حالة الملف الشخصي. على سبيل المثال، ينبّهك هذا الإعداد بسرعة إذا تم إصدار إصدار جديد من التطبيق لا يحتوي على "ملفات تعريف Baseline".

فرض تجميع "ملفات تعريف المرجع"

إذا كانت حالة تجميع ملفات Baseline Profile هي RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION، يمكنك فرض التجميع الفوري باستخدام adb:

adb shell cmd package compile -r bg-dexopt PACKAGE_NAME

التحقّق من حالة تجميع Baseline Profile بدون ProfileVerifier

إذا كنت لا تستخدم ProfileVerifier، يمكنك التحقّق من حالة التجميع باستخدام adb، مع العلم أنّها لا تقدّم إحصاءات مفصّلة مثل ProfileVerifier:

adb shell dumpsys package dexopt | grep -A 2 PACKAGE_NAME

يؤدي استخدام adb إلى إنتاج شيء مشابه لما يلي:

  [com.google.samples.apps.nowinandroid.demo]
    path: /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/base.apk
      arm64: [status=speed-profile] [reason=bg-dexopt] [primary-abi]
        [location is /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/oat/arm64/base.odex]

تشير قيمة الحالة إلى حالة تجميع الملف الشخصي، وهي إحدى القيم التالية:

حالة التجميع المعنى
speed‑profile يتوفّر ملف شخصي مجمَّع ويتم استخدامه.
verify لا يتوفّر ملف شخصي مجمَّع.

لا تعني حالة verify أنّ حزمة APK أو AAB لا تحتوي على ملف شخصي، لأنّه يمكن وضعها في قائمة الانتظار لتتم ترجمتها من خلال مهمة تحسين DEX التالية التي تعمل في الخلفية.

تشير قيمة السبب إلى ما يؤدي إلى تجميع الملف الشخصي، وهي إحدى القيم التالية:

السبب المعنى
install‑dm تم تجميع "ملف تعريف أساسي" يدويًا أو من خلال Google Play عند تثبيت التطبيق.
bg‑dexopt تم تجميع ملف شخصي أثناء عدم استخدام جهازك. قد يكون هذا الملف الشخصي ملفًا أساسيًا أو ملفًا تم جمعه أثناء استخدام التطبيق.
cmdline تم بدء عملية التجميع باستخدام adb. قد يكون هذا الملف الشخصي ملفًا أساسيًا أو ملفًا تم جمعه أثناء استخدام التطبيق.

التحقّق من تطبيق "ملف بدء التشغيل" في DEX وr8.json

يستخدم R8 قواعد Startup Profile في وقت الإنشاء لتحسين تنسيق الفئات في ملفات DEX. يختلف هذا التحسين في وقت الإنشاء عن طريقة استخدام &quot;ملفات Baseline Profile&quot; (baseline.prof)، إذ يتم تجميعها داخل حِزم APK أو AAB لكي ينفّذ ART عملية الترجمة على الجهاز. بما أنّ قواعد Startup Profile يتم تطبيقها أثناء عملية الإنشاء نفسها، لا يتوفّر ملف startup.prof منفصل داخل حزمة APK أو AAB لفحصه. يمكن ملاحظة تأثير ملفات Startup Profiles في تصميم ملف DEX بدلاً من ذلك.

فحص ترتيب DEX باستخدام r8.json (يُنصح به للإصدار 8.8 أو إصدار أحدث من "مكوّن Android الإضافي في Gradle")

بالنسبة إلى المشاريع التي تستخدم الإصدار 8.8 أو إصدارًا أحدث من &quot;المكوّن الإضافي لنظام Gradle المتوافق مع Android&quot;، يمكنك التحقّق مما إذا تم تطبيق &quot;ملف بدء التشغيل&quot; من خلال فحص ملف r8.json الذي تم إنشاؤه. يتم تجميع هذا الملف داخل حِزمة AAB.

  1. افتح حزمة تطبيق Android (AAB) وحدِّد موقع الملف r8.json.
  2. ابحث في الملف عن مصفوفة dexFiles التي تسرد ملفات DEX التي تم إنشاؤها.
  3. ابحث عن العنصر dexFiles الذي يحتوي على زوج المفتاح والقيمة "startup": true. يشير ذلك بوضوح إلى أنّه تم تطبيق قواعد ملف Startup Profile لتحسين تصميم ملف DEX المحدّد.

    "dexFiles": [
     {
       "checksum": "...",
       "startup": true // This flag confirms profile application to this DEX file
     },
     // ... other DEX files
    ]
    

فحص ترتيب DEX لجميع إصدارات "مكوّن Android الإضافي في Gradle"

إذا كنت تستخدم إصدارًا من "مكوّن Android الإضافي في Gradle" أقل من 8.8، فإنّ فحص ملفات DEX هو الطريقة الأساسية للتأكّد من تطبيق "ملف بدء التشغيل" بشكل صحيح. يمكنك أيضًا استخدام هذه الطريقة إذا كنت تستخدم الإصدار 8.8 أو إصدارًا أحدث من "مكوّن Android الإضافي في Gradle" وأردت التحقّق يدويًا من تنسيق DEX. على سبيل المثال، إذا لم تلاحظ تحسّنًا في الأداء على النحو المتوقّع. لفحص ترتيب DEX، اتّبِع الخطوات التالية:

  1. افتح حزمة AAB أو APK باستخدام إنشاء > تحليل حزمة APK في "استوديو Android".
  2. انتقِل إلى ملف DEX الأول. على سبيل المثال، classes.dex.
  3. افحص محتوى ملف DEX هذا. يجب أن تتمكّن من التأكّد من أنّ الفئات والأساليب المهمة المحدّدة في ملف Startup Profile (startup-prof.txt) متوفّرة في ملف DEX الأساسي هذا. يعني تقديم طلب ناجح أنّه سيتم منح الأولوية لهذه المكوّنات المهمة للمشاريع الناشئة من أجل تحميلها بشكل أسرع.

مشاكل في الأداء

يعرض هذا القسم بعض أفضل الممارسات لتحديد ملفاتك الأساسية وقياس أدائها بشكل صحيح من أجل تحقيق أقصى استفادة منها.

قياس مقاييس بدء التشغيل بشكل صحيح

ستكون "ملفات تعريف خط الأساس" أكثر فعالية إذا كانت مقاييس بدء التشغيل محددة جيدًا. المقياسان الأساسيان هما الوقت المُستغرَق للعرض الأولي (TTID) والوقت المُستغرَق للعرض الكامل (TTFD).

يحدث وقت التفاعل الأوّلي عندما يرسم التطبيق إطاره الأول. من المهم أن يكون هذا الوقت قصيرًا قدر الإمكان لأنّ عرض أي شيء يوضّح للمستخدم أنّ التطبيق قيد التشغيل. يمكنك حتى عرض مؤشر تقدّم غير محدّد لإظهار أنّ التطبيق متجاوب.

يشير TTFD إلى الوقت الذي يمكن فيه التفاعل مع التطبيق فعليًا. من المهم أن يكون هذا الوقت قصيرًا قدر الإمكان لتجنُّب إحباط المستخدمين. إذا أشرت بشكل صحيح إلى مقياس TTFD، ستُعلم النظام بأنّ الرمز الذي يتم تنفيذه أثناء عملية الوصول إلى مقياس TTFD هو جزء من عملية بدء تشغيل التطبيق. نتيجةً لذلك، يرجّح النظام وضع هذا الرمز في الملف الشخصي.

حاوِل إبقاء كلّ من TTID وTTFD في أدنى مستوى ممكن لجعل تطبيقك يبدو سريع الاستجابة.

يمكن للنظام رصد معرّف TTID وعرضه في Logcat وإدراجه كجزء من مقاييس الأداء عند بدء التشغيل. ومع ذلك، لا يمكن للنظام تحديد وقت العرض الأوّلي، ويقع على عاتق التطبيق مسؤولية إرسال تقرير عند وصوله إلى حالة تفاعلية مرسومة بالكامل. يمكنك إجراء ذلك من خلال استدعاء reportFullyDrawn() أو ReportDrawn إذا كنت تستخدم Jetpack Compose. إذا كانت لديك مهام متعدّدة تعمل في الخلفية ويجب إكمالها كلها قبل أن يُعدّ التطبيق قد تم عرضه بالكامل، يمكنك استخدام FullyDrawnReporter، كما هو موضّح في تحسين دقة توقيت بدء التشغيل.

الملفات الشخصية في المكتبة والملفات الشخصية المخصّصة

عند قياس أداء الملفات الشخصية، قد يكون من الصعب فصل مزايا ملفات تطبيقك الشخصية عن الملفات التي تساهم بها المكتبات، مثل مكتبات Jetpack. عند إنشاء حِزمة APK، يضيف المكوّن الإضافي لنظام Gradle المتوافق مع Android أي ملفات تعريف في البرامج الاعتمادية للمكتبة بالإضافة إلى ملف التعريف المخصّص. هذا الخيار مناسب لتحسين الأداء العام، وننصح باستخدامه في إصداراتك. ومع ذلك، يصعب قياس مقدار التحسّن الإضافي في الأداء الناتج عن ملفك المخصّص.

للاطّلاع يدويًا على التحسينات الإضافية التي يوفّرها ملفك الشخصي المخصّص، يمكنك إزالته وتشغيل مقاييس الأداء. بعد ذلك، استبدِلها وأعِد تشغيل مقاييس الأداء. ستوضّح لك مقارنة المقياسَين التحسينات التي توفّرها ملفات المكتبة وحدها، وملفات المكتبة بالإضافة إلى ملفك المخصّص.

تتمثّل إحدى الطرق التي يمكن من خلالها مقارنة الملفات الشخصية بشكل آلي في إنشاء صيغة جديدة للإنشاء لا تحتوي إلا على ملفات المكتبة الشخصية وليس ملفك الشخصي المخصّص. قارِن مقاييس الأداء من هذا الإصدار التجريبي بإصدار التطبيق الذي يتضمّن كلاً من ملفات المكتبة وملفاتك المخصّصة. يوضّح المثال التالي كيفية إعداد صيغة تتضمّن ملفات شخصية خاصة بالمكتبة فقط. أضِف صيغة جديدة باسم releaseWithoutCustomProfile إلى وحدة المستهلك الخاصة بملفك الشخصي، والتي تكون عادةً وحدة تطبيقك:

Kotlin

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    create("releaseWithoutCustomProfile") {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile(project(":baselineprofile"))
}

baselineProfile {
  variants {
    create("release") {
      from(project(":baselineprofile"))
    }
  }
}

Groovy

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    releaseWithoutCustomProfile {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile ':baselineprofile"'
}

baselineProfile {
  variants {
    release {
      from(project(":baselineprofile"))
    }
  }
}

يزيل مثال الرمز البرمجي السابق التبعية baselineProfile من جميع الصيغ ويطبّقها بشكل انتقائي على الصيغة release فقط. قد يبدو من غير المنطقي أنّه لا يزال يتمّ إضافة ملفات المكتبة الشخصية عند إزالة التبعية لوحدة إنتاج الملف الشخصي. ومع ذلك، فإنّ هذه الوحدة مسؤولة فقط عن إنشاء ملفك الشخصي المخصّص. لا يزال المكوّن الإضافي لنظام Gradle المتوافق مع Android يعمل مع جميع الصيغ، وهو المسؤول عن تضمين ملفات المكتبة.

عليك أيضًا إضافة خيار المنتج الجديد إلى وحدة إنشاء الملفات الشخصية. في هذا المثال، اسم وحدة المنتِج هو :baselineprofile.

Kotlin

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      create("releaseWithoutCustomProfile") {}
      ...
    }
  ...
}

Groovy

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      releaseWithoutCustomProfile {}
      ...
    }
  ...
}

عند تشغيل اختبار الأداء من &quot;استوديو Android&quot;، اختَر أحد متغيرات releaseWithoutCustomProfile لقياس الأداء باستخدام ملفات تعريف المكتبة فقط، أو اختَر أحد متغيرات release لقياس الأداء باستخدام ملفات تعريف المكتبة وملفات التعريف المخصّصة.

تجنُّب بدء تشغيل التطبيقات التي تتطلّب عمليات إدخال/إخراج

إذا كان تطبيقك يجري الكثير من عمليات الإدخال/الإخراج أو عمليات الشبكة أثناء بدء التشغيل، يمكن أن يؤثر ذلك سلبًا في كل من وقت بدء تشغيل التطبيق ودقة قياس الأداء عند بدء التشغيل. يمكن أن تستغرق هذه العمليات وقتًا غير محدد قد يختلف بمرور الوقت وحتى بين عمليات التكرار لنفس مقياس الأداء. تكون طلبات الإدخال/الإخراج أفضل بشكل عام من طلبات الشبكة، لأنّ الأخيرة يمكن أن تتأثر بعوامل خارجية وداخلية. تجنَّب إجراء طلبات بيانات من الشبكة أثناء بدء التشغيل. في حال كان استخدام أحدهما أو الآخر أمرًا لا مفر منه، استخدِم I/O.

ننصحك بأن يتيح تصميم تطبيقك بدء تشغيله بدون إجراء طلبات من الشبكة أو طلبات إدخال/إخراج، حتى إذا كان ذلك بغرض استخدامه عند قياس أداء بدء التشغيل. ويساعد ذلك في ضمان أقل تفاوت ممكن بين التكرارات المختلفة لمقاييس الأداء.

إذا كان تطبيقك يستخدم Hilt، يمكنك تقديم عمليات تنفيذ وهمية مرتبطة بالإدخال/الإخراج عند إجراء قياس الأداء في Microbenchmark وHilt.

تغطية جميع رحلات المستخدمين المهمة

من المهم تغطية جميع تجارب المستخدمين المهمة بدقة عند إنشاء &quot;الملف الأساسي&quot;. لن يتم تحسين أي رحلات مستخدمين غير مشمولة في "ملفات تعريف خط الأساس". تتضمّن ملفات تعريف الأداء الأساسية الأكثر فعالية جميع رحلات المستخدمين الشائعة عند بدء التشغيل، بالإضافة إلى رحلات المستخدمين داخل التطبيق التي تتطلّب أداءً عاليًا، مثل تصفّح القوائم.

تغييرات الملف الشخصي في وقت الترجمة في اختبار A/B

بما أنّ ملفات Startup وBaseline هي عمليات تحسين تتم في وقت الترجمة البرمجية، لا تتوافق عادةً مع الإصدارات العلنية عند إجراء اختبار أ/ب مباشرةً على حِزم APK مختلفة باستخدام &quot;متجر Google Play&quot;. لتقييم التأثير في بيئة مشابهة لبيئة الإنتاج، ننصحك باتّباع الطرق التالية:

  • الإصدار غير الدوري: يمكنك تحميل إصدار غير دوري إلى نسبة صغيرة من قاعدة المستخدمين لا تتضمّن سوى تغيير الملف الشخصي. يتيح لك ذلك جمع مقاييس واقعية حول الفرق في الأداء.

  • قياس الأداء على الجهاز: يمكنك قياس أداء تطبيقك على الجهاز مع تطبيق الملف الشخصي وبدونه. ومع ذلك، يُرجى العِلم أنّ قياس الأداء المحلي يعرض لك أفضل سيناريو ممكن للملفات الشخصية، لأنّه لا يتضمّن تأثيرات ملفات Cloud Profiles من ART المتوفّرة في الأجهزة المتاحة للبيع.