با استفاده از ویژگی های پیشرفته Crashlytics، خرابی های بازی Unity را درک کنید

1. مقدمه

در این نرم افزار کد، نحوه استفاده از ویژگی های پیشرفته Crashlytics را یاد خواهید گرفت که به شما دید بهتری نسبت به خرابی ها و شرایطی که ممکن است باعث آنها شده باشد، می دهد.

شما عملکرد جدیدی را به یک بازی نمونه اضافه خواهید کرد، MechaHamster: Level Up with Firebase Edition . این نمونه بازی نسخه جدیدی از بازی کلاسیک Firebase MechaHamster است که بیشتر قابلیت های Firebase داخلی آن را حذف می کند و به شما این شانس را می دهد که کاربردهای جدید Firebase را در جای خود پیاده سازی کنید.

یک منوی اشکال زدایی به بازی اضافه خواهید کرد. این منوی اشکال زدایی متدهایی را که شما می سازید فراخوانی می کند و به شما امکان می دهد عملکردهای مختلف Crashlytics را انجام دهید. این روش‌ها به شما نشان می‌دهند که چگونه گزارش‌های خرابی خودکار خود را با کلیدهای سفارشی، گزارش‌های ثبت سفارشی، خطاهای غیرمرگبار و موارد دیگر حاشیه‌نویسی کنید.

پس از ساختن بازی، از منوی اشکال زدایی استفاده می کنید و نتایج را بررسی می کنید تا دیدگاه منحصر به فردی را که آنها در مورد نحوه اجرای بازی شما در طبیعت ارائه می دهند را درک کنید.

چیزی که یاد خواهید گرفت

  • انواع خطاهایی که به طور خودکار توسط Crashlytics شناسایی می شوند.
  • خطاهای اضافی که می توانند به طور هدفمند ثبت شوند.
  • چگونه می توان اطلاعات بیشتری را به این خطاها اضافه کرد تا درک آنها آسان تر شود.

آنچه شما نیاز دارید

  • Unity (حداقل نسخه توصیه شده 2019+) با یکی یا هر دو مورد زیر:
    • پشتیبانی از ساخت iOS
    • پشتیبانی از ساخت اندروید
  • (فقط برای اندروید) Firebase CLI (برای آپلود نمادها برای گزارش‌های خرابی استفاده می‌شود)

2. محیط توسعه خود را تنظیم کنید

در بخش های زیر نحوه دانلود Level Up با کد Firebase و باز کردن آن در Unity توضیح داده شده است.

توجه داشته باشید که این بازی نمونه Level Up with Firebase توسط چندین کد لبه Firebase + Unity دیگر استفاده می شود، بنابراین ممکن است کارهای این بخش را قبلا انجام داده باشید. اگر چنین است، می توانید مستقیماً به آخرین مرحله در این صفحه بروید: "افزودن SDK های Firebase برای Unity".

کد را دانلود کنید

مخزن GitHub این Codelab را از خط فرمان کلون کنید:

git clone https://github.com/firebase/level-up-with-firebase.git

همچنین، اگر git را نصب نکرده‌اید، می‌توانید مخزن را به عنوان یک فایل ZIP دانلود کنید .

Level Up را با Firebase در ویرایشگر Unity باز کنید

  1. Unity Hub را اجرا کنید و از تب Projects ، روی فلش کشویی کنار Open کلیک کنید.
  2. روی افزودن پروژه از دیسک کلیک کنید.
  3. به دایرکتوری حاوی کد بروید و سپس روی OK کلیک کنید.
  4. اگر از شما خواسته شد، نسخه ویرایشگر Unity را برای استفاده و پلتفرم مورد نظر خود (اندروید یا iOS) انتخاب کنید.
  5. روی نام پروژه، level-up-with-firebase کلیک کنید و پروژه در ویرایشگر Unity باز می شود.
  6. اگر ویرایشگر شما به طور خودکار آن را باز نمی کند، MainGameScene در Assets > Hamster در تب Project از ویرایشگر Unity باز کنید.
    ff4ea3f3c0d29379.png

برای اطلاعات بیشتر در مورد نصب و استفاده از یونیتی، به کار در یونیتی مراجعه کنید.

3. Firebase را به پروژه Unity خود اضافه کنید

یک پروژه Firebase ایجاد کنید

  1. در کنسول Firebase ، روی افزودن پروژه کلیک کنید.
  2. برای ایجاد یک پروژه جدید، نام پروژه مورد نظر را وارد کنید.
    با این کار شناسه پروژه (که در زیر نام پروژه نمایش داده می شود) بر اساس نام پروژه نیز تعیین می شود. برای سفارشی سازی بیشتر می توانید به صورت اختیاری روی نماد ویرایش در شناسه پروژه کلیک کنید.
  3. در صورت درخواست، شرایط Firebase را بررسی کرده و بپذیرید.
  4. روی Continue کلیک کنید.
  5. گزینه Enable Google Analytics for this project را انتخاب کنید و سپس روی Continue کلیک کنید.
  6. یک حساب Google Analytics موجود را برای استفاده انتخاب کنید یا برای ایجاد حساب جدید Create a new account را انتخاب کنید.
  7. روی ایجاد پروژه کلیک کنید.
  8. پس از ایجاد پروژه، روی Continue کلیک کنید.

برنامه خود را با Firebase ثبت کنید

  1. هنوز در کنسول Firebase ، از مرکز صفحه نمای کلی پروژه، روی نماد Unity کلیک کنید تا گردش کار راه اندازی شود یا اگر قبلاً برنامه ای را به پروژه Firebase خود اضافه کرده اید، روی Add app کلیک کنید تا گزینه های پلتفرم نمایش داده شود.
  2. برای ثبت اهداف ساخت اپل (iOS) و Android انتخاب کنید.
  3. شناسه(های) پلتفرم خاص پروژه Unity خود را وارد کنید. برای این کد لبه موارد زیر را وارد کنید:
  4. (اختیاری) نام مستعار پلتفرم خاص پروژه Unity خود را وارد کنید.
  5. روی ثبت برنامه کلیک کنید و سپس به بخش Download config file بروید.

فایل های پیکربندی Firebase را اضافه کنید

پس از کلیک بر روی ثبت برنامه ، از شما خواسته می شود دو فایل پیکربندی را دانلود کنید (یک فایل پیکربندی برای هر هدف ساخت). پروژه Unity شما برای ارتباط با Firebase به فراداده Firebase در این فایل ها نیاز دارد.

  1. هر دو فایل کانفیگ موجود را دانلود کنید:
    • برای اپل (iOS) : GoogleService-Info.plist را دانلود کنید.
    • برای اندروید : google-services.json را دانلود کنید.
  2. پنجره Project پروژه Unity خود را باز کنید، سپس هر دو فایل پیکربندی را به پوشه Assets منتقل کنید.
  3. به کنسول Firebase برگردید، در گردش کار راه اندازی، روی Next کلیک کنید و به Add Firebase SDKs for Unity بروید.

SDK های Firebase را برای Unity اضافه کنید

  1. روی Download Firebase Unity SDK در کنسول Firebase کلیک کنید.
  2. SDK را در جایی مناسب از حالت فشرده خارج کنید.
  3. در پروژه Unity باز خود، به Assets > Import Package > Custom Package بروید.
  4. در گفتگوی بسته واردات ، به دایرکتوری حاوی SDK خارج شده بروید، FirebaseAnalytics.unitypackage انتخاب کنید و سپس روی Open کلیک کنید.
  5. از کادر گفتگوی Import Unity Package که ظاهر می‌شود، روی Import کلیک کنید.
  6. مراحل قبلی را برای وارد کردن FirebaseCrashlytics.unitypackage تکرار کنید.
  7. به کنسول Firebase برگردید و در گردش کار راه اندازی، روی Next کلیک کنید.

برای اطلاعات بیشتر در مورد افزودن Firebase SDK به پروژه‌های Unity، گزینه‌های نصب Unity اضافی را ببینید.

4. Crashlytics را در پروژه Unity خود راه اندازی کنید

برای استفاده از Crashlytics در پروژه‌های Unity، باید چند مرحله راه‌اندازی دیگر را انجام دهید. البته، شما باید SDK را مقداردهی اولیه کنید. اما همچنین، باید نمادهای خود را آپلود کنید تا بتوانید stacktraces نمادین را در کنسول Firebase مشاهده کنید، و برای اطمینان از اینکه Firebase رویدادهای خرابی شما را دریافت می‌کند، باید یک خرابی آزمایشی را مجبور کنید.

Crashlytics SDK را راه اندازی کنید

  1. در Assets/Hamster/Scripts/MainGame.cs ، using عبارات زیر را اضافه کنید:
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    
    ماژول اول به شما امکان می دهد از روش هایی از Crashlytics SDK استفاده کنید و دومی شامل برخی از برنامه های افزودنی برای C# Tasks API است. بدون using دستورات هر دو، کد زیر کار نخواهد کرد.
  2. هنوز در MainGame.cs ، با فراخوانی InitializeFirebaseAndStartGame() مقداردهی اولیه Firebase را به متد Start() موجود اضافه کنید:
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. و دوباره، در MainGame.cs ، InitializeFirebaseAndStartGame() را پیدا کنید، یک متغیر برنامه را اعلام کنید، و سپس پیاده سازی متد را مانند این بازنویسی کنید:
    public Firebase.FirebaseApp app = null;
    
    // Begins the firebase initialization process and afterwards, opens the main menu.
    private void InitializeFirebaseAndStartGame()
    {
      Firebase.FirebaseApp.CheckAndFixDependenciesAsync()
      .ContinueWithOnMainThread(
        previousTask => 
        {
          var dependencyStatus = previousTask.Result;
          if (dependencyStatus == Firebase.DependencyStatus.Available) {
            // Create and hold a reference to your FirebaseApp,
            app = Firebase.FirebaseApp.DefaultInstance;
            // Set the recommended Crashlytics uncaught exception behavior.
            Crashlytics.ReportUncaughtExceptionsAsFatal = true;
            InitializeCommonDataAndStartGame();
          } else {
            UnityEngine.Debug.LogError(
              $"Could not resolve all Firebase dependencies: {dependencyStatus}\n" +
              "Firebase Unity SDK is not safe to use here");
          }
        });
    }
    

قرار دادن منطق اولیه در اینجا از تعامل بازیکن قبل از شروع اولیه وابستگی های Firebase جلوگیری می کند.

مزایا و اثرات گزارش استثناهای کنترل نشده به عنوان کشنده در سؤالات متداول Crashlytics مورد بحث قرار گرفته است.

پروژه خود را بسازید و نمادها را آپلود کنید

مراحل ساخت و آپلود نمادها برای اپلیکیشن های iOS و اندروید متفاوت است.

iOS+ (پلتفرم اپل)

  1. از کادر گفتگوی Build Settings ، پروژه خود را به فضای کاری Xcode صادر کنید.
  2. اپلیکیشن خود را بسازید
    برای پلتفرم‌های اپل، افزونه Firebase Unity Editor پروژه Xcode شما را به‌طور خودکار پیکربندی می‌کند تا برای هر ساخت، یک فایل نماد سازگار با Crashlytics را در سرورهای Firebase آپلود کند. این اطلاعات نمادها برای دیدن ردپای پشته نمادین در داشبورد Crashlytics مورد نیاز است.

اندروید

  1. (فقط در طول راه اندازی اولیه، نه برای هر ساخت) ساخت خود را تنظیم کنید:
    1. یک پوشه جدید به نام Builds در ریشه دایرکتوری پروژه خود ایجاد کنید (یعنی به عنوان خواهر یا برادر دایرکتوری Assets خود)، و سپس یک پوشه فرعی به نام Android ایجاد کنید.
    2. در File > Build Settings > Player Settings > Configuration ، Scripting Backend را روی IL2CPP قرار دهید.
      • IL2CPP به طور کلی باعث می شود که ساخت ها کوچکتر شوند و عملکرد بهتری داشته باشند.
      • IL2CPP همچنین تنها گزینه موجود در iOS است و انتخاب آن در اینجا به دو پلتفرم اجازه می‌دهد برابری بهتری داشته باشند و تفاوت‌های اشکال زدایی بین این دو را ساده‌تر کند (اگر بخواهید هر دو را بسازید).
  2. اپلیکیشن خود را بسازید در File > Build Settings موارد زیر را تکمیل کنید:
    1. مطمئن شوید که Create symbols.zip علامت زده شده باشد (یا اگر با یک کشویی نمایش داده شد، Debugging را انتخاب کنید).
    2. APK خود را مستقیماً از ویرایشگر Unity در زیر پوشه Builds/Android که به تازگی ساخته اید بسازید.
  3. هنگامی که ساخت شما به پایان رسید، باید یک فایل نماد سازگار با Crashlytics ایجاد کنید و آن را در سرورهای Firebase آپلود کنید. این اطلاعات نمادها برای دیدن ردپای نمادین پشته برای خرابی های کتابخانه بومی در داشبورد Crashlytics مورد نیاز است.

    این فایل نمادها را با اجرای دستور Firebase CLI زیر ایجاد و آپلود کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID : شناسه برنامه Android Firebase شما (نه نام بسته شما). این مقدار را در فایل google-services.json که قبلا دانلود کرده اید پیدا کنید. این مقدار mobilesdk_app_id است.
      ID برنامه اندروید Firebase مثال: 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS : مسیر فایل نماد زیپ شده که در دایرکتوری Builds/Android پس از اتمام ساخت شما ایجاد می شود (به عنوان مثال: Builds/Android/myapp-1.0-v100.symbols.zip ).

اجبار یک خرابی آزمایشی برای پایان راه‌اندازی

برای تکمیل راه‌اندازی Crashlytics و مشاهده داده‌های اولیه در داشبورد Crashlytics کنسول Firebase، باید یک خرابی آزمایشی را اجباری کنید.

  1. در MainGameScene EmptyObject GameObject در Hierarchy ویرایشگر پیدا کنید، اسکریپت زیر را به آن اضافه کنید و سپس صحنه را ذخیره کنید. این اسکریپت چند ثانیه پس از اجرای برنامه خود باعث خرابی تست می شود.
    using System;
    using UnityEngine;
    
    public class CrashlyticsTester : MonoBehaviour {
        // Update is called once per frame
        void Update()
        {
            // Tests your Crashlytics implementation by
            // throwing an exception every 60 frames.
            // You should see reports in the Firebase console
            // a few minutes after running your app with this method.
            if(Time.frameCount >0 && (Time.frameCount%60) == 0)
            {
                throw new System.Exception("Test exception; please ignore");
            }
        }
    }
    
  2. برنامه خود را بسازید و اطلاعات نماد را پس از اتمام ساخت خود آپلود کنید.
    • iOS : افزونه Firebase Unity Editor به طور خودکار پروژه Xcode شما را برای آپلود فایل نماد شما پیکربندی می کند.
    • Android : دستور Firebase CLI crashlytics:symbols:upload برای آپلود فایل نماد خود اجرا کنید.
  3. برنامه خود را اجرا کنید پس از اجرا شدن برنامه، گزارش دستگاه را تماشا کنید و منتظر بمانید تا استثنا از CrashlyticsTester فعال شود.
    • iOS : گزارش‌ها را در قسمت پایین Xcode مشاهده کنید.
    • Android : با اجرای دستور زیر در ترمینال، گزارش‌ها را مشاهده کنید: adb logcat .
  4. برای مشاهده استثناء، از داشبورد Crashlytics دیدن کنید! آن را در جدول مشکلات در پایین داشبورد خواهید دید. بعداً در نرم افزار کد، درباره نحوه کاوش این گزارش ها بیشتر خواهید آموخت.
  5. هنگامی که تأیید کردید رویداد در Crashlytics آپلود شده است، EmptyObject GameObject که آن را به آن پیوست کرده‌اید انتخاب کنید، فقط مؤلفه CrashlyticsTester را حذف کنید و سپس صحنه را ذخیره کنید تا آن را به حالت اولیه بازگردانید.

5. منوی Debug را فعال و درک کنید

تاکنون، Crashlytics را به پروژه Unity خود اضافه کرده‌اید، راه‌اندازی را تمام کرده‌اید و تأیید کرده‌اید که Crashlytics SDK رویدادها را در Firebase بارگذاری می‌کند. اکنون یک منو در پروژه یونیتی خود ایجاد می کنید که نحوه استفاده از عملکرد پیشرفته تر Crashlytics را در بازی خود نشان می دهد. پروژه Level Up with Firebase Unity از قبل دارای منوی Debug مخفی است که می توانید آن را قابل مشاهده کنید و عملکرد آن را بنویسید.

منوی Debug را فعال کنید

دکمه دسترسی به منوی اشکال زدایی در پروژه Unity شما وجود دارد، اما در حال حاضر فعال نیست. برای دسترسی به آن از پیش ساخته MainMenu باید دکمه را فعال کنید:

  1. در ویرایشگر Unity، پیش ساخته ای به نام MainMenu باز کنید. 4148538cbe9f36c5.png
  2. در سلسله مراتب پیش ساخته، شی فرعی غیرفعال شده با نام DebugMenuButton را پیدا کنید و سپس آن را انتخاب کنید. 816f8f9366280f6c.png
  3. DebugMenuButton را با علامت زدن کادر موجود در گوشه سمت چپ بالا در سمت چپ فیلد متنی حاوی DebugMenuButton فعال کنید. 8a8089d2b4886da2.png
  4. پیش ساخته را ذخیره کنید.
  5. بازی را در ویرایشگر یا در دستگاه خود اجرا کنید. اکنون منو باید در دسترس باشد.

پیش نمایش و درک بدنه روش برای منوی اشکال زدایی

بعداً در این نرم‌افزار، بدنه‌های متد را برای برخی از روش‌های Crashlytics اشکال‌زدایی از پیش پیکربندی شده می‌نویسید. اگرچه در پروژه Level Up with Firebase Unity، متدها در DebugMenu.cs تعریف و فراخوانی می شوند.

در حالی که برخی از این روش‌ها هم متدهای Crashlytics را فراخوانی می‌کنند و هم خطاهای پرتاب می‌کنند، توانایی Crashlytics برای تشخیص این خطاها به فراخوانی آن متدها در ابتدا بستگی ندارد. در عوض، گزارش‌های خرابی که از خطاهای شناسایی خودکار ایجاد می‌شوند، با اطلاعات اضافه شده توسط این روش‌ها افزایش می‌یابند.

DebugMenu.cs را باز کنید و سپس روش های زیر را پیدا کنید:

روش‌هایی برای ایجاد و حاشیه‌نویسی مشکلات Crashlytics:

  • CrashNow
  • LogNonfatalError
  • LogStringsAndCrashNow
  • SetAndOverwriteCustomKeyThenCrash
  • SetLogsAndKeysBeforeANR

روش‌هایی برای ثبت رویدادهای Analytics برای کمک به اشکال‌زدایی:

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

در مراحل بعدی این کد لبه، شما این روش‌ها را پیاده‌سازی می‌کنید و یاد می‌گیرید که چگونه به موقعیت‌های خاصی که ممکن است در توسعه بازی رخ دهد، کمک کنند.

6. از تحویل گزارش های خرابی در حال توسعه اطمینان حاصل کنید

قبل از اینکه شروع به پیاده‌سازی این روش‌های اشکال‌زدایی کنید و ببینید که چگونه بر گزارش‌های خرابی تأثیر می‌گذارند، مطمئن شوید که نحوه گزارش رویدادها به Crashlytics را می‌دانید.

برای پروژه های یونیتی، رویدادهای کرش و استثنا در بازی شما بلافاصله روی دیسک نوشته می شوند. برای استثناهای کشف نشده که بازی شما را خراب نمی‌کنند (به عنوان مثال، استثناهای C# در منطق بازی)، می‌توانید از Crashlytics SDK بخواهید با تنظیم ویژگی Crashlytics.ReportUncaughtExceptionsAsFatal true را به عنوان رویدادهای مرگبار گزارش کند. . این رویدادها به صورت بلادرنگ و بدون نیاز به کاربر نهایی برای راه اندازی مجدد بازی به Crashlytics گزارش می شود. توجه داشته باشید که خرابی‌های بومی همیشه به‌عنوان رویدادهای مرگبار گزارش می‌شوند و زمانی که کاربر نهایی بازی را مجدداً راه‌اندازی می‌کند، ارسال می‌شود.

علاوه بر این، از تفاوت‌های کوچک اما مهم زیر بین نحوه ارسال اطلاعات Crashlytics توسط محیط‌های مختلف زمان اجرا به Firebase آگاه باشید:

شبیه ساز iOS:

  • اطلاعات Crashlytics در صورت جدا کردن Xcode از شبیه ساز گزارش می شود. اگر Xcode ضمیمه شود، خطاها را در بالادست شناسایی می کند و از تحویل اطلاعات جلوگیری می کند.

دستگاه های فیزیکی موبایل (اندروید و iOS):

  • مختص Android: ANR ها فقط در Android 11+ گزارش می شوند. ANR ها و رویدادهای غیر کشنده در اجرای بعدی گزارش می شوند.

ویرایشگر یونیتی:

تست کرش کردن بازی خود با لمس یک دکمه در CrashNow()

پس از راه‌اندازی Crashlytics در بازی‌تان، Crashlytics SDK به‌طور خودکار خرابی‌ها و استثناهای کشف نشده را ثبت می‌کند و آنها را برای تجزیه و تحلیل در Firebase آپلود می‌کند. و گزارش ها در داشبورد Crashlytics در کنسول Firebase نمایش داده می شوند.

  1. برای نشان دادن اینکه این واقعاً خودکار است: DebugMenu.cs را باز کنید و سپس متد CrashNow() را به صورت زیر بازنویسی کنید:
    void CrashNow()
    {
        TestCrash();
    }
    
  2. اپلیکیشن خود را بسازید
  3. (فقط اندروید) نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. روی دکمه Crash Now ضربه بزنید و به مرحله بعدی این کد لبه بروید تا نحوه مشاهده و تفسیر گزارش خرابی را بیابید.

7. گزارش های مشکل را در کنسول Firebase درک کنید

وقتی نوبت به مشاهده گزارش‌های خرابی شما می‌رسد، چیزهای بیشتری وجود دارد که باید در مورد نحوه استفاده حداکثری از آنها بدانید. هر یک از روش هایی که می نویسید نشان می دهد که چگونه می توان انواع مختلف اطلاعات را به گزارش های Crashlytics اضافه کرد.

  1. روی دکمه Crash Now ضربه بزنید و سپس برنامه خود را مجددا راه اندازی کنید.
  2. به داشبورد Crashlytics بروید. به جدول مشکلات در پایین داشبورد بروید، جایی که Crashlytics رویدادهایی را که همگی علت اصلی یکسانی دارند در «مشکلات» گروه‌بندی می‌کند.
  3. روی شماره جدیدی که در جدول Issues فهرست شده است کلیک کنید. با انجام این کار، خلاصه رویداد مربوط به هر رویداد جداگانه ای که به Firebase ارسال شده است، نمایش داده می شود.

    شما باید چیزی شبیه تصویر زیر را ببینید. توجه داشته باشید که چگونه خلاصه رویداد به طور برجسته رد پشته تماسی را که منجر به خرابی شده است نشان می دهد. 40c96abe7f90c3aa.png

فراداده اضافی

یکی دیگر از برگه های مفید، تب Unity Metadata است. این بخش شما را در مورد ویژگی‌های دستگاهی که رویداد روی آن رخ داده است، از جمله ویژگی‌های فیزیکی، مدل/مشخصات CPU و انواع معیارهای GPU مطلع می‌کند.

در اینجا یک مثال است که در آن اطلاعات موجود در این برگه ممکن است مفید باشد:
تصور کنید بازی شما به شدت از شیدرها برای دستیابی به ظاهری خاص استفاده می کند، اما همه گوشی ها دارای پردازنده گرافیکی نیستند که قادر به ارائه این ویژگی باشند. اطلاعات موجود در برگه Unity Metadata می‌تواند به شما ایده بهتری درباره سخت‌افزاری که برنامه شما باید هنگام تصمیم‌گیری درباره اینکه چه ویژگی‌هایی را به طور خودکار در دسترس یا غیرفعال می‌کند، آزمایش کند، ارائه دهد.

در حالی که ممکن است یک باگ یا خرابی هرگز در دستگاه شما اتفاق نیفتد، به دلیل تنوع گسترده دستگاه های Android در طبیعت، به درک بهتر «نقاط داغ» خاص دستگاه های مخاطبان شما کمک می کند.

41d8d7feaa87454d.png

8. پرتاب، گرفتن، و ثبت یک استثنا

اغلب اوقات، به‌عنوان یک توسعه‌دهنده، حتی اگر کد شما به‌درستی یک استثنا در زمان اجرا را دریافت کرده و مدیریت می‌کند، خوب است توجه داشته باشید که در چه شرایطی رخ داده است. Crashlytics.LogException می توان دقیقاً برای این هدف مورد استفاده قرار داد - برای ارسال یک رویداد استثنایی به Firebase تا بتوانید بیشتر مشکل را در کنسول Firebase اشکال زدایی کنید.

  1. در Assets/Hamster/Scripts/States/DebugMenu.cs ، موارد زیر را به عبارات using اضافه کنید:
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. هنوز در DebugMenu.cs ، LogNonfatalError() به صورت زیر بازنویسی کنید:
    void LogNonfatalError()
    {
        try
        {
            throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
        }
        catch(System.Exception exception)
        {
            Crashlytics.LogException(exception);
        }
    }
    
  3. اپلیکیشن خود را بسازید
  4. (فقط اندروید) نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. روی دکمه Log Nonfatal Error ضربه بزنید و سپس برنامه خود را مجددا راه اندازی کنید.
  6. به داشبورد Crashlytics بروید، و باید چیزی شبیه به آنچه در آخرین مرحله از این کد لبه مشاهده کردید، مشاهده کنید.
  7. با این حال، این بار، فیلتر نوع رویداد را به Non-fatals محدود کنید تا فقط خطاهای غیر کشنده را مشاهده کنید، مانند آنچه که به تازگی وارد سیستم شده اید.
    a39ea8d9944cbbd9.png

9. برای درک بهتر جریان اجرای برنامه، رشته ها را به Crashlytics وارد کنید

آیا تا به حال سعی کرده اید بفهمید که چرا یک خط کد که از چندین مسیر، صدها اگر نه هزاران بار در هر جلسه فراخوانی می شود، می تواند ناگهان یک استثنا ایجاد کند یا خراب شود؟ اگرچه ممکن است خوب باشد که کد را در یک IDE گام برداریم و مقادیر را با دقت بیشتری بررسی کنیم، اگر این فقط در میان درصد بسیار کمی از کاربران شما اتفاق بیفتد، چه؟ حتی بدتر از آن، اگر هر کاری که می‌کنید نتوانید این تصادف را تکرار کنید، چه می‌کنید؟

در چنین موقعیت‌هایی، داشتن زمینه‌ای می‌تواند دنیای متفاوتی ایجاد کند. با Crashlytics.Log ، می‌توانید متن مورد نیاز خود را بنویسید. این پیام ها را به عنوان نکاتی برای آینده خود در مورد آنچه ممکن است در جریان باشد در نظر بگیرید.

در حالی که گزارش‌ها را می‌توان به روش‌های بی‌شماری مورد استفاده قرار داد، اما معمولاً برای ضبط موقعیت‌هایی که ترتیب و/یا عدم وجود تماس‌ها بخش مهمی از اطلاعات است، بسیار مفید هستند.

  1. در Assets/Hamster/Scripts/States/DebugMenu.cs ، LogStringsAndCrashNow() به صورت زیر بازنویسی کنید:
    void LogStringsAndCrashNow()
    {
        Crashlytics.Log($"This is the first of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        const bool RUN_OPTIONAL_PATH = false;
        if(RUN_OPTIONAL_PATH)
        {
            Crashlytics.Log(" As it stands, this log should not appear in your records because it will never be called.");
        }
        else
        {
            Crashlytics.Log(" A log that will simply inform you which path of logic was taken. Akin to print debugging.");
        }
        Crashlytics.Log($"This is the second of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        TestCrash();
    }
    
  2. اپلیکیشن خود را بسازید
  3. (فقط اندروید) نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. روی دکمه Log Strings و Crash Now ضربه بزنید و سپس برنامه خود را مجددا راه اندازی کنید.
  5. به داشبورد Crashlytics برگردید و روی جدیدترین شماره فهرست شده در جدول مشکلات کلیک کنید. باز هم باید چیزی شبیه به شماره های قبلی ببینید.
    7aabe103b8589cc7.png
  6. با این حال، اگر روی برگه گزارش‌ها در خلاصه رویداد کلیک کنید، نمایی مانند زیر دریافت خواهید کرد:
    4e27aa407b7571cf.png

10. یک کلید سفارشی بنویسید و بازنویسی کنید

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

علاوه بر ثبت رشته‌های دلخواه، Crashlytics شکل دیگری از اشکال‌زدایی را ارائه می‌کند، زمانی که دانستن وضعیت دقیق برنامه شما هنگام خرابی مفید است: کلیدهای سفارشی.

اینها جفت های کلید-مقدار هستند که می توانید برای یک جلسه تنظیم کنید. برخلاف گزارش‌هایی که انباشته می‌شوند و صرفاً افزودنی هستند، کلیدها را می‌توان بازنویسی کرد تا فقط آخرین وضعیت یک متغیر یا شرایط را منعکس کند.

این کلیدها علاوه بر اینکه دفتر کل آخرین وضعیت ثبت شده برنامه شما هستند، می توانند به عنوان فیلترهای قدرتمند برای مشکلات Crashlytics استفاده شوند.

  1. در Assets/Hamster/Scripts/States/DebugMenu.cs ، SetAndOverwriteCustomKeyThenCrash() به صورت زیر بازنویسی کنید:
    void SetAndOverwriteCustomKeyThenCrash()
    {
        const string CURRENT_TIME_KEY = "Current Time";
        System.TimeSpan currentTime = System.DateTime.Now.TimeOfDay;
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString() // Values must be strings
            );
    
        // Time Passes
        currentTime += DayDivision.DURATION_THAT_ENSURES_PHASE_CHANGE;
    
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString()
            );
        TestCrash();
    }
    
  2. اپلیکیشن خود را بسازید
  3. (فقط اندروید) نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. روی دکمه Set Custom Key and Crash ضربه بزنید و سپس برنامه خود را مجددا راه اندازی کنید.
  5. به داشبورد Crashlytics برگردید و روی جدیدترین شماره فهرست شده در جدول مشکلات کلیک کنید. باز هم باید چیزی شبیه به شماره های قبلی ببینید.
  6. با این حال، این بار، روی برگه کلیدها در خلاصه رویداد کلیک کنید تا بتوانید ارزش کلیدها از جمله Current Time را مشاهده کنید:
    7dbe1eb00566af98.png

چرا می خواهید از کلیدهای سفارشی به جای گزارش های سفارشی استفاده کنید؟

  • گزارش‌ها در ذخیره‌سازی داده‌های متوالی خوب هستند، اما اگر فقط آخرین مقدار را بخواهید، کلیدهای سفارشی بهتر هستند.
  • در کنسول Firebase، می‌توانید به راحتی مسائل را بر اساس مقادیر کلیدها در کادر جستجوی جدول Issues فیلتر کنید.

با این حال، مانند گزارش‌ها، کلیدهای سفارشی محدودیتی دارند. Crashlytics حداکثر 64 جفت کلید-مقدار را پشتیبانی می کند. پس از رسیدن به این آستانه، مقادیر اضافی ذخیره نمی شوند. هر جفت کلید-مقدار می تواند تا 1 کیلوبایت اندازه داشته باشد.

11. (فقط اندروید) از کلیدها و گزارش‌های سفارشی برای درک و تشخیص ANR استفاده کنید

یکی از سخت‌ترین کلاس‌های مشکلات برای اشکال‌زدایی برای توسعه‌دهندگان اندروید، خطای Application Not Responsing (ANR) است. ANR زمانی اتفاق می‌افتد که برنامه برای بیش از 5 ثانیه به ورودی پاسخ ندهد. اگر این اتفاق بیفتد، به این معنی است که برنامه یا مسدود شده است، یا بسیار کند پیش می رود. یک گفتگو به کاربران نشان داده می‌شود و آنها می‌توانند انتخاب کنند که آیا «صبر کنید» یا «بستن برنامه».

ANR ها تجربه کاربری بدی هستند و (همانطور که در پیوند ANR در بالا ذکر شد) می توانند بر قابلیت کشف برنامه شما در فروشگاه Google Play تأثیر بگذارند. به دلیل پیچیدگی آنها، و به دلیل اینکه اغلب توسط کدهای چند رشته ای با رفتارهای بسیار متفاوت در مدل های مختلف تلفن ایجاد می شوند، بازتولید ANR در حین اشکال زدایی اغلب بسیار دشوار است، اگر تقریباً غیرممکن نباشد. به این ترتیب، رویکرد تحلیلی و قیاسی به آنها معمولا بهترین رویکرد است.

در این روش، از ترکیبی از Crashlytics.LogException ، Crashlytics.Log و Crashlytics.SetCustomKey برای تکمیل گزارش خودکار مشکلات و ارائه اطلاعات بیشتر به ما استفاده خواهیم کرد.

  1. در Assets/Hamster/Scripts/States/DebugMenu.cs ، SetLogsAndKeysBeforeANR() به صورت زیر بازنویسی کنید:
    void SetLogsAndKeysBeforeANR()
    {
        System.Action<string,long> WaitAndRecord =
        (string methodName, long targetCallLength)=>
        {
            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
            const string CURRENT_FUNCTION = "Current Async Function";
    
            // Initialize key and start timing
            Crashlytics.SetCustomKey(CURRENT_FUNCTION, methodName);
            stopWatch.Start();
    
            // The actual (simulated) work being timed.
            BusyWaitSimulator.WaitOnSimulatedBlockingWork(targetCallLength);
    
            // Stop timing
            stopWatch.Stop();
    
            if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.EXTREME_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough to cause an ANR.");
            }
            else if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.SEVERE_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough it may cause an ANR");
            }
        };
    
        WaitAndRecord("DoSafeWork",1000L);
        WaitAndRecord("DoSevereWork",BusyWaitSimulator.SEVERE_DURATION_MILLIS);
        WaitAndRecord("DoExtremeWork",2*BusyWaitSimulator.EXTREME_DURATION_MILLIS);
    }
    
  2. اپلیکیشن خود را بسازید
  3. نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. روی دکمه با برچسب Set Logs And Keys → ANR ضربه بزنید و سپس برنامه خود را مجددا راه اندازی کنید.
  5. به داشبورد Crashlytics برگردید و سپس روی شماره جدید در جدول Issues کلیک کنید تا خلاصه رویداد را مشاهده کنید. اگر تماس به درستی انجام شد، باید چیزی شبیه به این را ببینید:
    876c3cff7037bd07.png

    همانطور که می بینید، Firebase انتظار شلوغ روی رشته را به عنوان دلیل اصلی برنامه شما برای ایجاد ANR مشخص کرده است.
  6. اگر به گزارش های موجود در برگه Logs خلاصه رویداد نگاه کنید، خواهید دید که آخرین روش ثبت شده به عنوان کامل DoSevereWork است.
    5a4bec1cf06f6984.png

    در مقابل، آخرین روش لیست شده به عنوان شروع DoExtremeWork است که نشان می دهد ANR در طول این روش رخ داده است و بازی قبل از اینکه بتواند DoExtremeWork ثبت کند بسته شد.

    89d86d5f598ecf3a.png

چرا این کار را انجام دهید؟

  • بازتولید ANR فوق‌العاده سخت است، بنابراین دریافت اطلاعات غنی در مورد ناحیه کد و معیارها برای یافتن آن به صورت قیاسی بسیار مهم است.
  • با اطلاعات ذخیره شده در کلیدهای سفارشی، اکنون می‌دانید که کدام رشته ناهمگام طولانی‌ترین زمان را برای اجرا به طول می‌انجامد و کدام یک در خطر راه‌اندازی ANR هستند. این نوع داده‌های منطقی و عددی مرتبط به شما نشان می‌دهند که کد شما در کجای کد شما برای بهینه‌سازی بیشتر ضروری است.

12. تلاقی رویدادهای تجزیه و تحلیل برای غنی سازی بیشتر گزارش ها

روش‌های زیر نیز از منوی اشکال‌زدایی قابل فراخوانی هستند، اما به جای ایجاد مشکلات، از Google Analytics به عنوان منبع اطلاعات دیگری برای درک بهتر عملکرد بازی شما استفاده می‌کنند.

برخلاف روش‌های دیگری که در این نرم‌افزار نوشته‌اید، باید از این روش‌ها در ترکیب با روش‌های دیگر استفاده کنید. قبل از اجرای یکی از روش‌ها، این روش‌ها را (با فشار دادن دکمه مربوط به آن‌ها در منوی اشکال‌زدایی) به هر ترتیب دلخواه که می‌خواهید فراخوانی کنید. سپس، هنگامی که اطلاعات مربوط به موضوع خاص Crashlytics را بررسی می‌کنید، یک گزارش منظم از رویدادهای Analytics را مشاهده خواهید کرد. این داده‌ها را می‌توان در یک بازی برای درک بهتر ترکیبی از جریان برنامه یا ورودی کاربر، بسته به اینکه برنامه‌تان را ابزارسازی کرده‌اید، استفاده کرد.

  1. در Assets/Hamster/Scripts/States/DebugMenu.cs ، پیاده‌سازی‌های موجود روش‌های زیر را بازنویسی کنید:
    public void LogProgressEventWithStringLiterals()
    {
          Firebase.Analytics.FirebaseAnalytics.LogEvent("progress", "percent", 0.4f);
    }
    
    public void LogIntScoreWithBuiltInEventAndParams()
    {
          Firebase.Analytics.FirebaseAnalytics
            .LogEvent(
              Firebase.Analytics.FirebaseAnalytics.EventPostScore,
              Firebase.Analytics.FirebaseAnalytics.ParameterScore,
              42
            );
    }
    
  2. بازی خود را بسازید و اجرا کنید و سپس وارد منوی Debug شوید.
  3. (فقط اندروید) نمادهای خود را با اجرای دستور Firebase CLI زیر بارگذاری کنید:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. برای فراخوانی عملکردهای بالا حداقل یکی از دکمه های زیر را یک یا چند بار فشار دهید:
    • ثبت رویداد رشته
    • ورود رویداد Int
  5. دکمه Crash Now را فشار دهید.
  6. بازی خود را مجدداً راه اندازی کنید تا رویداد خرابی را در Firebase آپلود کند.
  7. وقتی توالی‌های دلخواه مختلفی از رویدادهای Analytics را ثبت می‌کنید و سپس از بازی‌تان می‌خواهید رویدادی ایجاد کند که Crashlytics گزارشی از آن ایجاد می‌کند (همانطور که شما دارید)، آنها به برگه Logs در خلاصه رویداد Crashlytics اضافه می‌شوند:
    d3b16d78f76bfb04.png

13. جلو رفتن

و با آن، شما باید مبنای نظری بهتری داشته باشید که بر اساس آن می توانید گزارش های خرابی خود را که به طور خودکار تولید می شود تکمیل کنید. این اطلاعات جدید به شما امکان می دهد از وضعیت فعلی، سوابق رویدادهای گذشته و رویدادهای Google Analytics موجود برای تجزیه بهتر توالی رویدادها و منطقی که منجر به نتیجه آن شده است استفاده کنید.

اگر برنامه شما Android 11 (سطح API 30) یا بالاتر را هدف قرار می‌دهد، GWP-ASan را در نظر بگیرید، یک ویژگی اختصاص‌دهنده حافظه بومی که برای اشکال‌زدایی خرابی‌های ناشی از خطاهای حافظه بومی مانند اشکالات use-after-free و heap-buffer-overflow مفید است. برای استفاده از این ویژگی اشکال زدایی، GWP-ASan را به صراحت فعال کنید .

مراحل بعدی

به بازی Instrument your Unity با Remote Config codelab بروید، جایی که با استفاده از Remote Config و A/B Testing در Unity آشنا خواهید شد.