অ্যাপ্লিকেশনের UI থ্রেড ৫ সেকেন্ডের বেশি সময় ধরে সাড়া না দিলে অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ত্রুটি দেখা দেয়। আপনি Android ডকুমেন্টেশনে ANR এবং ANR নির্ণয় সম্পর্কে আরও পড়তে পারেন।
উপরন্তু, 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
যেকোনো থ্রেড যা ধীর I/O অপারেশন চালাচ্ছিল এবং ব্লক করছিল 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 )
সুপারিশ
সাধারণভাবে, আপনার অ্যাপটি মূল থ্রেডে ব্যয়বহুল I/O অপারেশন চালানো উচিত নয়। মূল থ্রেডের ক্ষেত্রে IO Root blocking , আপনি মূল থ্রেডে ঘটে যাওয়া যেকোনো অনিচ্ছাকৃত I/O অপারেশন সনাক্ত করতে স্ট্রিক মোড ব্যবহার করতে পারেন।
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
একটি থ্রেড ট্যাগ করা হয়েছে ANR ট্রিগার করা থ্রেডটি কি Unknown root cause । মূল কারণ নির্ধারণের জন্য 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 প্রতিরোধ করার জন্য সাধারণ পরামর্শ অনুসরণ করুন। উদাহরণস্বরূপ, আপনার কোডের সেই স্থানগুলি চিহ্নিত করুন যেখানে অ্যাপের মূল থ্রেড 5 সেকেন্ডের বেশি ব্যস্ত থাকতে পারে।