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