اشکال زدایی ANR

حل ANR ها در بازی Unity شما یک فرآیند سیستماتیک است:

شکل ۱. مراحل حل ANRها در بازی‌های Unity.

ادغام سرویس‌های گزارش‌دهی

سرویس‌های گزارش‌دهی مانند Android Vitals ، Firebase Crashlytics و Backtrace (یک شریک معتبر Unity) ثبت خطا و تجزیه و تحلیل آن را برای بازی شما در مقیاس بزرگ ارائه می‌دهند. SDKهای سرویس‌های گزارش‌دهی را در اوایل چرخه توسعه در بازی خود ادغام کنید. تجزیه و تحلیل کنید که کدام سرویس گزارش‌دهی به بهترین وجه با نیازها و بودجه بازی شما مطابقت دارد.

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

ادغام SDK های گزارش دهنده بر عملکرد بازی یا اندازه APK تأثیر نمی گذارد.

نمادها را تحلیل کنید

گزارش‌های سرویس گزارش‌دهی خود را تجزیه و تحلیل کنید و بررسی کنید که آیا ردپاهای پشته در قالب قابل خواندن توسط انسان هستند یا خیر. برای اطلاعات بیشتر به Symbolicate Android crashes و ANR برای بازی‌های Unity مراجعه کنید.

شکل ۲. Crashlytics که شناسه ساخت و نمادهای libil2cpp.so را نشان می‌دهد.

نحوه بررسی شناسه ساخت نماد

اگر سیستم گزارش‌دهی، شناسه ساخت (Build ID) را نشان ندهد اما نمادهای ساخت (Build Symbols) هنوز در حافظه دستگاه ساخت (Build Machine) وجود داشته باشند، می‌توان شناسه ساخت نمادها را بررسی کرد و سپس آنها را در سرویس گزارش‌دهی آپلود کرد. در غیر این صورت، برای آپلود فایل‌های نماد، به یک نسخه جدید از ساخت (Build) نیاز است.

در ویندوز یا macOS:

  1. بر اساس اسکریپت نویسی خود به پوشه نمادها بروید (به وضوح مراجعه کنید :)
    1. از دستور زیر استفاده کنید (در ویندوز، از Cygwin برای اجرای ابزار readelf استفاده کنید)
    2. استفاده از Grep برای فیلتر کردن خروجی متن اختیاری است.
    3. به دنبال شناسه ساخت (Build ID) باشید
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

بررسی کد بازی

وقتی ردیابی پشته، تابعی را در کتابخانه libil2cpp.so نشان می‌دهد، خطا در کد C# رخ داده است که به C++ تبدیل شده است. کتابخانه libil2cpp.so نه تنها کد بازی شما، بلکه افزونه‌ها و بسته‌ها را نیز در خود جای داده است.

نام فایل C++ از نام اسمبلی تعریف شده در پروژه Unity پیروی می‌کند. در غیر این صورت، نام فایل، نام پیش‌فرض Assembly-C# است. برای مثال، شکل 3 خطای مربوط به فایل Game.cpp (با رنگ آبی مشخص شده) را نشان می‌دهد که نامی است که در فایل Assembly Definition تعریف شده است. Logger نام کلاس (با رنگ قرمز مشخص شده) در اسکریپت C# است که به دنبال آن نام تابع (با رنگ سبز مشخص شده) آمده است. در نهایت نام کاملی که مبدل IL2CPP تولید کرده است (با رنگ نارنجی مشخص شده) آمده است.

شکل ۳. پشته فراخوانی پروژه آزمایشی از Backtrace.

با انجام موارد زیر، کد بازی خود را بررسی کنید:

  • پروژه C# را برای یافتن هرگونه کد مشکوک بررسی کنید. معمولاً استثنائات مدیریت نشده C# باعث ANR یا خرابی برنامه نمی‌شوند. با این حال، مطمئن شوید که کد در موقعیت‌های مختلف به درستی اجرا می‌شود. بررسی کنید که آیا کد از یک ماژول موتور شخص ثالث استفاده می‌کند یا خیر، و تحلیل کنید که آیا نسخه اخیر باعث ایجاد خطا شده است یا خیر. علاوه بر این، بررسی کنید که آیا اخیراً Unity را به‌روزرسانی کرده‌اید یا اینکه خطا فقط در دستگاه‌های خاص رخ می‌دهد.
  • بازی را به عنوان یک پروژه اندروید استودیو صادر کنید . با دسترسی کامل به کد منبع C# تبدیل شده بازی خود، می‌توانید تابعی را که باعث ANR می‌شود پیدا کنید. کد C++ با کد C# شما بسیار متفاوت به نظر می‌رسد و تبدیل کد به ندرت با مشکل مواجه می‌شود. اگر موردی پیدا کردید، یک تیکت پشتیبانی برای Unity ارسال کنید.
  • کد منبع بازی را بررسی کنید و مطمئن شوید که هرگونه منطقی که در فراخوانی‌های OnApplicationFocus() و OnApplicationPause() اجرا می‌شود، به طور مناسب اصلاح شده است.
    • موتور یونیتی برای مکث در اجرای خود، یک زمان وقفه دارد؛ بار کاری بیش از حد در این فراخوانی‌های برگشتی می‌تواند باعث ANR شود.
    • برای بهبود تحلیل داده‌های خود، به بخش‌هایی از کد، لاگ یا اطلاعات مسیر اضافه کنید.
  • از Unity Profiler برای بررسی عملکرد بازی استفاده کنید. پروفایل کردن برنامه شما همچنین می‌تواند راهی عالی برای شناسایی گلوگاه‌هایی باشد که ممکن است باعث ANR شوند.
  • یک راه عالی برای شناسایی عملیات ورودی/خروجی طولانی در نخ اصلی، استفاده از حالت strict mode است.
  • تاریخچه Android Vitals یا سایر سرویس‌های گزارش‌دهی را تجزیه و تحلیل کنید و نسخه‌های انتشار بازی که خطا در آن‌ها بیشترین میزان را دارد، بررسی کنید. کد منبع خود را در تاریخچه کنترل نسخه خود مرور کنید و تغییرات کد را بین نسخه‌ها مقایسه کنید. اگر مورد مشکوکی پیدا کردید، هر تغییر یا راه‌حل احتمالی را به صورت جداگانه آزمایش کنید.
  • تاریخچه گزارش‌های ANR گوگل پلی را برای دستگاه‌ها و نسخه‌های اندروید که بیشترین ANR را دریافت می‌کنند، بررسی کنید. اگر دستگاه‌ها یا نسخه‌ها قدیمی هستند، احتمالاً می‌توانید با خیال راحت آنها را نادیده بگیرید، البته اگر این کار روی سودآوری بازی تأثیری نداشته باشد. داده‌ها را با دقت مطالعه کنید زیرا گروه خاصی از کاربران دیگر نمی‌توانند بازی شما را انجام دهند. برای اطلاعات بیشتر، به داشبورد توزیع مراجعه کنید.
  • کد منبع بازی را بررسی کنید تا مطمئن شوید کدی را فراخوانی نمی‌کنید که ممکن است باعث ایجاد مشکل شود، برای مثال، finish اگر به درستی استفاده نشود می‌تواند مخرب باشد. برای کسب اطلاعات بیشتر در مورد توسعه اندروید، به راهنماهای توسعه‌دهندگان اندروید مراجعه کنید.
  • پس از بررسی داده‌ها و خروجی گرفتن از ساخت بازی به اندروید استودیو، شما با کد C و C++ سر و کار دارید و بنابراین می‌توانید از ابزارهایی فراتر از راه‌حل‌های استاندارد یونیتی، مانند Android Memory Profiler ، Android CPU Profiler و perfetto، نهایت استفاده را ببرید.

کد موتور یونیتی

برای اینکه بدانید آیا ANR در سمت موتور Unity اتفاق می‌افتد یا خیر، در ردپاهای پشته libUnity.so یا libMain.so را بررسی کنید. اگر آنها را پیدا کردید، مراحل زیر را انجام دهید:

  • ابتدا، کانال‌های انجمن ( انجمن‌های یونیتی ، بحث‌های یونیتی ، Stackoverflow ) را جستجو کنید.
  • اگر چیزی پیدا نکردید، برای حل مشکل، یک باگ ثبت کنید . یک ردگیری پشته نمادین ارائه دهید تا مهندسان موتور بتوانند خطا را بهتر درک کرده و حل کنند.
  • بررسی کنید که آیا آخرین نسخه Unity LTS بهبودهایی در رابطه با مشکلات شما ایجاد کرده است یا خیر. در این صورت، بازی خود را برای استفاده از آن نسخه ارتقا دهید. (این راه حل ممکن است فقط برای برخی از توسعه دهندگان امکان پذیر باشد.)
  • اگر کد شما به جای Activity سفارشی استفاده می‌کند، کد جاوا را بررسی کنید تا مطمئن شوید که اکتیویتی مشکلی ایجاد نمی‌کند.

SDK شخص ثالث

  • بررسی کنید که همه کتابخانه‌های شخص ثالث به‌روز باشند و گزارشی از خرابی یا ANR برای آخرین نسخه اندروید نداشته باشند.
  • به انجمن‌های Unity بروید تا ببینید آیا خطاهایی در نسخه‌های بعدی برطرف شده‌اند یا اینکه Unity یا یکی از اعضای انجمن راه‌حلی ارائه داده است.
  • گزارش ANR گوگل پلی را بررسی کنید و مطمئن شوید که خطا قبلاً توسط گوگل شناسایی نشده باشد. گوگل از برخی ANRها آگاه است و به طور فعال در حال رفع آنها است.

کتابخانه سیستم

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

دلایل خروج

ApplicationExitInfo یک API اندروید برای درک علل ANR است. اگر بازی شما از Unity 6 یا بالاتر استفاده می‌کند، می‌توانید ApplicationExitInfo مستقیماً فراخوانی کنید. برای نسخه‌های قدیمی‌تر Unity، باید افزونه خودتان را پیاده‌سازی کنید تا فراخوانی‌های ApplicationExitInfo از Unity فعال شود.

Crashlytics همچنین از ApplicationExitInfo استفاده می‌کند؛ با این حال، پیاده‌سازی خودتان کنترل دقیق‌تری به شما می‌دهد و شما را قادر می‌سازد اطلاعات مرتبط‌تری را وارد کنید.