خطاهای Application Not Responding (ANR) زمانی فعال می شوند که رشته رابط کاربری برنامه بیش از 5 ثانیه پاسخ ندهد. میتوانید درباره ANR و تشخیص ANR در مستندات Android اطلاعات بیشتری کسب کنید.
علاوه بر این، Crashlytics می تواند به شناسایی رشته های مشکل دار خاص کمک کند. ما ANR ها را تجزیه و تحلیل می کنیم، و سپس، در داشبورد Crashlytics ، رشته های قابل اجرا را برچسب گذاری می کنیم تا نکاتی در مورد نحوه اشکال زدایی ANR ارائه کنیم.
بخشهای زیر در این صفحه توضیح میدهند که هر تگ ANR به چه معناست، یک مثال ANR را با آن تگ نشان میدهد و راهحل پیشنهادی برای رفع اشکال ANR ارائه میدهد.
Triggered ANR
رشتهای که برای مدت طولانی مسدود شده بود و باعث ایجاد ANR میشد با این حاشیهنویسی میشود برچسب Triggered ANR
.
رشته مشکل دار می تواند رشته اصلی برنامه یا هر رشته ای باشد که پاسخگو نیست. با این حال، موضوع با عنوان برچسب گذاری شده است Triggered ANR
ممکن است علت واقعی ANR باشد یا نباشد. برای ارائه اطلاعاتی برای اشکالزدایی و رفع این ANRها، Crashlytics همچنین هر رشته دیگری را که در ANR دخیل است برچسبگذاری میکند. در بخشهای بعدی این صفحه، با سایر برچسبهایی که میتوان روی یک موضوع اعمال کرد، آشنا شوید.
Deadlocked
هر رشتهای که مشخص شود درگیر بنبستی است که به ANR منجر شده است، با این توضیح داده میشود. برچسب Deadlocked
.
بن بست زمانی رخ می دهد که یک رشته وارد حالت انتظار می شود زیرا یک منبع مورد نیاز توسط رشته دیگری نگه داشته می شود، که همچنین منتظر منبعی است که توسط نخ اول نگهداری می شود. اگر رشته اصلی برنامه در این وضعیت باشد، احتمال وقوع ANR وجود دارد.
مشاهده نمونه
در اینجا دو موضوع درگیر یک بن بست وجود دارد:
main (unknown): tid=1 systid=1568
com.android.server.pm.PackageManagerService$PackageManagerInternalImpl.getPackage(PackageManagerService.java:22701)
com.android.server.pm.PackageManagerService$PackageManagerInternalImpl.filterOnlySystemPackages(PackageManagerService.java:22787)
...
com.android.server.SystemServer.main(SystemServer.java:368)
java.lang.reflect.Method.invoke(Native method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:517)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)
ActivityManager (unknown): tid=21 systid=1902
com.android.server.pm.PackageManagerService.getPackageSetting(PackageManagerService.java:23618)
com.android.server.pm.PackageManagerService.getPackageUid(PackageManagerService.java:4542)
...
android.os.Handler.handleCallback(Handler.java:907)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:216)
android.os.HandlerThread.run(HandlerThread.java:67)
com.android.server.ServiceThread.run(ServiceThread.java:44)
توصیه
به موضوعات درگیر در بن بست نگاه کنید و منابع/قفل های به دست آمده توسط آن رشته ها را بررسی کنید. برای راه حل های ممکن به الگوریتم های پیشگیری از بن بست و بن بست مراجعه کنید.
IO Root blocking
هر رشتهای که عملیات ورودی/خروجی کند را اجرا میکند و مسدود میکند رشته Triggered ANR
با حاشیه نویسی شده است تگ IO Root blocking
. اگر رشته Triggered ANR
توسط رشتههای دیگر مسدود نمیشود، سپس موضوع IO Root blocking
نیز یک است نخ Root blocking
مشاهده نمونه ها
Thread main(THREAD_STATE_TIMED_WAITING)
sun.misc.Unsafe.park( Unsafe.java:0 )
java.util.concurrent.locks.LockSupport.parkNanos( LockSupport.java:230 )
android.database.sqlite.SQLiteConnectionPool.waitForConnection( SQLiteConnectionPool.java:756 )
...
android.app.ActivityThread.main( ActivityThread.java:8192 )
Thread main(THREAD_STATE_NATIVE_WAITING)
Syscall
art::ConditionVariable::WaitHoldingLocks(art::Thread*)
art::GoToRunnable(art::Thread*)
art::JniMethodEnd(unsigned int, art::Thread*)
libcore.io.Linux.fdatasync( Linux.java:0 )
libcore.io.ForwardingOs.fdatasync( ForwardingOs.java:105 )
...
java.io.RandomAccessFile.write( RandomAccessFile.java:559 )
...
android.app.ActivityThread.main( ActivityThread.java:8192 )
توصیه
به طور کلی، برنامه شما نباید عملیات گران قیمت ورودی/خروجی را روی رشته اصلی اجرا کند. در مورد موضوع اصلی بودن IO Root blocking
، همچنین میتوانید از حالت سختگیرانه برای شناسایی هرگونه عملیات ورودی/خروجی غیرعمدی که در رشته اصلی اتفاق میافتد استفاده کنید.
Root blocking
هر رشته ای که موضوع را مسدود کند به عنوان برچسب گذاری شده است Triggered ANR
با حاشیه نویسی شده است تگ Root blocking
اگر یک موضوع به عنوان هر دو برچسب گذاری شود Root blocking
و Triggered ANR
، پس هیچ رشته دیگری وجود ندارد که آن رشته را مسدود کند.
در صورت وجود رشتههای Triggered ANR
منتظر رشتههای دیگر بودند (شاید به صورت گذرا). Root blocking
دلایل مختلفی می تواند وجود داشته باشد که چرا یک موضوع علت اصلی ANR است.
مشاهده نمونه ها
در اینجا چند مثال بر اساس وضعیت نخ آورده شده است:
Thread main(THREAD_STATE_RUNNABLE)
android.os.Parcel.createTypedArray( Parcel.java:3086 )
android.content.pm.PackageInfo.<init>( PackageInfo.java:546 )
...
android.app.ActivityThread$H.handleMessage( ActivityThread.java:2166 )
android.os.Handler.dispatchMessage( Handler.java:106 )
android.os.Looper.loop( Looper.java:246 )
android.app.ActivityThread.main( ActivityThread.java:8633 )
Thread main(THREAD_STATE_BLOCKED)
DBHelper.runOnDB( DBHelper.java:97 )
DBHelper.runDb( DBHelper.java:125 )
...
java.lang.reflect.Method.invoke( Method.java:0 )
EventBus.invokeSubscriber( EventBus.java:510 )
postToSubscription( EventBus.java:437 )
...
android.os.Handler.handleCallback( Handler.java:938 )
android.os.Handler.dispatchMessage( Handler.java:99 )
android.os.Looper.loop( Looper.java:268 )
android.app.ActivityThread.main( ActivityThread.java:7904 )
توصیه
کار فشرده CPU را در موضوع اصلی به حداقل برسانید. برای انجام کارهای فشرده CPU از نخ های کارگر یا پس زمینه استفاده کنید.
کار فشرده I/O را، مانند بارگیری از پایگاه داده، روی رشته اصلی به حداقل برسانید.
Unknown root cause
یک موضوع با برچسب برچسب گذاری شده است تگ Unknown root cause
در صورتی که رشته ای باشد که ANR را راه اندازی کرده است اما در هنگام وقوع ANR بیکار بوده است. Crashlytics اطلاعات کافی برای تعیین علت اصلی ندارد. هیچ دلیل واضحی وجود ندارد که چرا این ANR رخ داده است.
مشاهده نمونه
Thread main(THREAD_STATE_NATIVE_WAITING) __epoll_pwait
android::Looper::pollInner(int)
android::Looper::pollOnce(int, int*, int*, void**)
android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)
android.os.MessageQueue.nativePollOnce( MessageQueue.java:0 )
android.os.MessageQueue.next( MessageQueue.java:335 )
android.os.Looper.loop( Looper.java:193 )
android.app.ActivityThread.main( ActivityThread.java:8019 )
توصیه
توصیه های کلی در مورد نحوه جلوگیری از ANR را دنبال کنید. برای مثال، مکانهایی را در کد خود شناسایی کنید که رشته اصلی برنامه میتواند بیش از ۵ ثانیه در آنها مشغول باشد.