Crashlytics ড্যাশবোর্ডে ANR ট্যাগের উপর ভিত্তি করে আপনার Android অ্যাপ ডিবাগ করুন

অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ত্রুটিগুলি ট্রিগার হয় যখন অ্যাপ্লিকেশনটির UI থ্রেড 5 সেকেন্ডের বেশি সময় ধরে সাড়া না দেয়। আপনি Android ডকুমেন্টেশনে ANR এবং ANR নির্ণয় সম্পর্কে আরও পড়তে পারেন।

উপরন্তু, Crashlytics নির্দিষ্ট সমস্যাযুক্ত থ্রেড চিহ্নিত করতে সাহায্য করতে পারে। আমরা ANR বিশ্লেষণ করি, এবং তারপর, Crashlytics ড্যাশবোর্ডে , আমরা কীভাবে ANR ডিবাগ করতে হয় তার ইঙ্গিত দিতে প্রযোজ্য থ্রেডগুলিকে ট্যাগ করি।

এই পৃষ্ঠার নিম্নলিখিত বিভাগগুলি প্রতিটি ANR ট্যাগের অর্থ কী তা ব্যাখ্যা করে, সেই ট্যাগের সাথে একটি উদাহরণ ANR দেখায় এবং ANR ডিবাগ করার জন্য একটি প্রস্তাবিত সমাধান প্রদান করে৷

Triggered ANR

একটি থ্রেড যা অনেকক্ষণ অবরুদ্ধ ছিল এবং ANR ট্রিগার করেছে তা এর সাথে টীকা করা হয়েছে Triggered ANR ট্যাগ।

সমস্যাযুক্ত থ্রেড অ্যাপের প্রধান থ্রেড হতে পারে, অথবা কোনো থ্রেড অপ্রতিক্রিয়াশীল বলে পাওয়া যেতে পারে। যাইহোক, থ্রেড হিসাবে ট্যাগ Triggered ANR ANR এর প্রকৃত কারণ হতে পারে বা নাও হতে পারে। এই ANRগুলি ডিবাগিং এবং ঠিক করার জন্য অন্তর্দৃষ্টি প্রদান করতে, Crashlytics এএনআর-এর সাথে জড়িত অন্য কোনো থ্রেডকে ট্যাগ করে। এই পৃষ্ঠার নিম্নলিখিত বিভাগে, অন্যান্য ট্যাগগুলি সম্পর্কে জানুন যা একটি থ্রেডে প্রয়োগ করা যেতে পারে।

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

একটি থ্রেড সঙ্গে ট্যাগ করা হয় 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 প্রতিরোধ করা যায় সে সম্পর্কে সাধারণ পরামর্শ অনুসরণ করুন। উদাহরণস্বরূপ, আপনার কোডের সেই স্থানগুলি চিহ্নিত করুন যেখানে অ্যাপের প্রধান থ্রেড 5 সেকেন্ডের বেশি সময় ধরে ব্যস্ত থাকতে পারে৷

,

অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ত্রুটিগুলি ট্রিগার হয় যখন অ্যাপ্লিকেশনটির UI থ্রেড 5 সেকেন্ডের বেশি সময় ধরে সাড়া না দেয়। আপনি Android ডকুমেন্টেশনে ANR এবং ANR নির্ণয় সম্পর্কে আরও পড়তে পারেন।

উপরন্তু, Crashlytics নির্দিষ্ট সমস্যাযুক্ত থ্রেড চিহ্নিত করতে সাহায্য করতে পারে। আমরা ANR বিশ্লেষণ করি, এবং তারপর, Crashlytics ড্যাশবোর্ডে , আমরা কীভাবে ANR ডিবাগ করতে হয় তার ইঙ্গিত দিতে প্রযোজ্য থ্রেডগুলিকে ট্যাগ করি।

এই পৃষ্ঠার নিম্নলিখিত বিভাগগুলি প্রতিটি ANR ট্যাগের অর্থ কী তা ব্যাখ্যা করে, সেই ট্যাগের সাথে একটি উদাহরণ ANR দেখায় এবং ANR ডিবাগ করার জন্য একটি প্রস্তাবিত সমাধান প্রদান করে৷

Triggered ANR

একটি থ্রেড যা অনেকক্ষণ অবরুদ্ধ ছিল এবং ANR ট্রিগার করেছে তা এর সাথে টীকা করা হয়েছে Triggered ANR ট্যাগ।

সমস্যাযুক্ত থ্রেড অ্যাপের প্রধান থ্রেড হতে পারে, অথবা কোনো থ্রেড অপ্রতিক্রিয়াশীল বলে পাওয়া যেতে পারে। যাইহোক, থ্রেড হিসাবে ট্যাগ Triggered ANR ANR এর প্রকৃত কারণ হতে পারে বা নাও হতে পারে। এই ANRগুলি ডিবাগিং এবং ঠিক করার জন্য অন্তর্দৃষ্টি প্রদান করতে, Crashlytics এএনআর-এর সাথে জড়িত অন্য কোনো থ্রেডকে ট্যাগ করে। এই পৃষ্ঠার নিম্নলিখিত বিভাগে, অন্যান্য ট্যাগগুলি সম্পর্কে জানুন যা একটি থ্রেডে প্রয়োগ করা যেতে পারে।

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

একটি থ্রেড সঙ্গে ট্যাগ করা হয় 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 প্রতিরোধ করা যায় সে সম্পর্কে সাধারণ পরামর্শ অনুসরণ করুন। উদাহরণস্বরূপ, আপনার কোডের সেই স্থানগুলি চিহ্নিত করুন যেখানে অ্যাপের প্রধান থ্রেড 5 সেকেন্ডের বেশি সময় ধরে ব্যস্ত থাকতে পারে৷