ANR (Application Not Responding) হল Android এর একটি সিস্টেম বিজ্ঞপ্তি যা দেখা যায় যখন অ্যাপ 5 সেকেন্ডের মধ্যে ইনপুটে সাড়া দেয় না। গ্লিচ (UI ব্লকিং ছাড়া লজিক্যাল ত্রুটি) এবং ল্যাগ (সম্পূর্ণ বন্ধ না হয়ে ধীরগতি) থেকে ভিন্ন, ANR হল একটি গুরুতর ব্যর্থতা যা অপারেটিং সিস্টেম দ্বারা রেকর্ড করা হয়: Android “অ্যাপ সাড়া দিচ্ছে না” ডায়ালগ দেখায় যাতে বন্ধ বা অপেক্ষা করার বিকল্প থাকে। Android Vitals Documentation অনুসারে, 0.5% এর বেশি ANR রেটযুক্ত অ্যাপগুলি Google Play এ কম রেটিং পায় এবং সুপারিশ থেকে লুকানো হতে পারে। নির্ণয়ের মধ্যে /data/anr/traces.txt বিশ্লেষণ, StrictMode ব্যবহার এবং প্রধান থ্রেডের প্রোফাইলিং অন্তর্ভুক্ত।
মূল বিষয়
ANR (Application Not Responding) হল Android এর একটি ব্যবহারকারী সুরক্ষা ব্যবস্থা যা সক্রিয় হয় যখন অ্যাপ ইনপুটে সাড়া দেওয়া বন্ধ করে দেয়। সিস্টেম ইভেন্ট প্রসেসিং সময় ট্র্যাক করে: যদি BroadcastReceiver 10 সেকেন্ডের মধ্যে onReceive সম্পূর্ণ না করে, Service 20 সেকেন্ডের মধ্যে onCreate থেকে ফিরে না আসে, বা ContentProvider 15 সেকেন্ডের মধ্যে সাড়া না দেয় — Android ANR তৈরি করে।
যখন ANR হয়, Android সমস্ত উইন্ডোর উপরে একটি সিস্টেম ডায়ালগ দেখায়: “অ্যাপ সাড়া দিচ্ছে না। আপনি কি এটি বন্ধ করতে বা অপেক্ষা করতে চান?” ব্যবহারকারী অ্যাপটি বন্ধ করতে বা এটি পুনরুদ্ধারের জন্য অপেক্ষা করতে পারেন। যদি ANR ঘন ঘন ঘটে, ব্যবহারকারী অ্যাপটি আনইনস্টল করে দেন। Google Play তার র্যাঙ্কিং অ্যালগরিদমে ANR রেট — ANR সহ সেশনের শতাংশ — বিবেচনা করে।
iOS এ সিস্টেম ডায়ালগ সহ ANR এর কোনো সমতুল্য নেই। পরিবর্তে, Apple Watchdog ব্যবহার করে, যা 0x8badf00d এক্সিট কোড দিয়ে প্রক্রিয়া শেষ করে। ব্যবহারকারী কোনো ডায়ালগ দেখেন না — অ্যাপটি কেবল হোম স্ক্রিনে বন্ধ হয়ে যায়। এটি Android এ ANR ব্যবহারকারীর জন্য আরও লক্ষণীয় করে তোলে, কিন্তু সিস্টেমকে আরও নির্ণয়ের তথ্য দেয়।
ANR ঘটে যখন সিস্টেম চারটি উপাদানের একটির জন্য টাইমআউট ট্র্যাক করে। প্রতিটি উপাদানের নিজস্ব সময়সীমা রয়েছে।
BroadcastReceiver প্রধান থ্রেডে এক্সিকিউট হয়। যদি onReceive একটি সিঙ্ক্রোনাস নেটওয়ার্ক অনুরোধ শুরু করে, ডাটাবেসে দীর্ঘ লেখে, বা লকের জন্য অপেক্ষা করে — 10 সেকেন্ডের মধ্যে ANR ঘটে। সমাধান: ব্যাকগ্রাউন্ড প্রসেসিংয়ের জন্য goAsync() এবং WorkManager ব্যবহার করুন। একটি সাধারণ পরিস্থিতি হল FCM থেকে Push বিজ্ঞপ্তি পাওয়া এবং Room এ সিঙ্ক্রোনাসভাবে সংরক্ষণ করা।
Service.onCreate এবং Service.onStartCommand এর 20 সেকেন্ডের সীমা রয়েছে। যদি সার্ভিস প্রধান থ্রেডে ভারী আরম্ভীকরণ (লাইব্রেরি লোড করা, নেটওয়ার্ক থেকে কনফিগারেশন পড়া) শুরু করে — ANR অনিবার্য। ব্যাকগ্রাউন্ডে নিশ্চিত এক্সিকিউশনের জন্য IntentService (অপ্রচলিত) বা WorkManager ব্যবহার করুন।
ContentProvider.onCreate Application.onCreate এর আগে এক্সিকিউট হয় এবং এর 15 সেকেন্ডের সীমা রয়েছে। যদি প্রোভাইডার ডাটাবেস মাইগ্রেশন করে, অভিধান লোড করে, বা নেটওয়ার্ক থেকে SDK আরম্ভ করে — এটি অ্যাপ স্টার্টআপে ANR ঘটায়। সমাধান: অলস আরম্ভীকরণ, ভারী অপারেশন WorkManager এ স্থানান্তর।
Android ANR বিশ্লেষণের জন্য বেশ কয়েকটি সরঞ্জাম সরবরাহ করে: সিস্টেম লগ থেকে বিশেষায়িত লাইব্রেরি পর্যন্ত।
প্রতিটি ANR এ, Android সমস্ত অ্যাপ থ্রেডের স্ট্যাক ডাম্প সহ /data/anr/traces.txt ফাইল সংরক্ষণ করে। “main” থ্রেড খুঁজুন — স্ট্যাকের শেষ পদ্ধতি কারণ নির্দেশ করে। সাধারণ প্যাটার্ন: Thread.sleep(), InputStream.read(), BinderProxy.transact()। ডিভাইস থেকে ফাইল বের করতে, সুপারইউজার বিশেষাধিকার সহ adb ব্যবহার করুন।
Firebase Crashlytics স্বয়ংক্রিয়ভাবে ANR সংগ্রহ করে এবং ট্রেস সহ ড্যাশবোর্ডে দেখায়। Android 11+ এর জন্য, ANR রিপোর্ট প্রধান থ্রেডের সম্পূর্ণ স্ট্যাক সহ আসে। সংহতকরণের জন্য নির্ভরতা যোগ করা এবং Application.onCreate এ FirebaseApp আরম্ভ করা প্রয়োজন।
Android Studio তে CPU Profiler আপনাকে অ্যাপ ট্রেস রেকর্ড করতে এবং দেখতে দেয় কোন পদ্ধতিগুলি CPU সময় নিচ্ছে। “Record with method traces” সক্রিয় করুন এবং ANR সৃষ্টিকারী পরিস্থিতি পুনরায় তৈরি করুন। টাইমলাইন দেখাবে হ্যাং-এর সময় প্রধান থ্রেডে কোন পদ্ধতিগুলি চলছিল।
Android এ ANR সংগ্রহের জন্য Firebase Crashlytics সংহতকরণের উদাহরণ:
class App : Application() {
override fun onCreate() {
super.onCreate()
FirebaseApp.initializeApp(this)
FirebaseCrashlytics.getInstance()
.setCrashlyticsCollectionEnabled(true)
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
}
}
ANR ঠিক করার অর্থ মূলত সমস্ত দীর্ঘ অপারেশন প্রধান থ্রেড থেকে ব্যাকগ্রাউন্ড থ্রেডে স্থানান্তর করা। আসুন প্রতিটি উপাদানের জন্য নির্দিষ্ট কৌশল দেখি।
WorkManager ব্যাকগ্রাউন্ড কাজের জন্য Google এর সুপারিশকৃত সমাধান। এটি ডিভাইসের অবস্থা বিবেচনা করে ব্যাকগ্রাউন্ড থ্রেডে কাজ সম্পাদনের নিশ্চয়তা দেয়। Service এর বিপরীতে, WorkManager প্রধান থ্রেড ব্লক করে না এবং অ্যাপ পুনরায় চালু হওয়ার প্রতিরোধী। BroadcastReceiver এর জন্য, goAsync() ব্যবহার করুন এবং PendingResult WorkManager এ পাস করুন।
সমস্ত নেটওয়ার্ক অনুরোধ, ডাটাবেস অপারেশন এবং ফাইল I/O Dispatchers.IO দিয়ে চালান। প্রধান থ্রেড শুধুমাত্র UI আপডেট করা উচিত। Activity ধ্বংস হলে স্বয়ংক্রিয় করুটিন বাতিলের জন্য viewModelScope ব্যবহার করুন। যেকোনো প্রসঙ্গে runBlocking() এড়িয়ে চলুন — এটি বর্তমান থ্রেডকে সিঙ্ক্রোনাসভাবে ব্লক করে।
যদি ContentProvider ধীর আরম্ভীকরণ করে, অলস লোডিং প্রক্রিয়া ব্যবহার করুন: একটি প্রোভাইডার তৈরি করুন যা অবিলম্বে ডেটা ফেরত দেয় এবং WorkManager এর মাধ্যমে বিলম্বের সাথে ভারী আরম্ভীকরণ শুরু করুন। এটি অ্যাপ স্টার্টআপে ANR প্রতিরোধ করে, যখন সিস্টেম বিলম্বের জন্য সবচেয়ে সংবেদনশীল।
Android এ goAsync সহ BroadcastReceiver এর সঠিক ব্যবহারের উদাহরণ:
class FcmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val pendingResult = goAsync()
WorkManager.getInstance(context!!)
.enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
pendingResult.finish()
}
}
ANR মোকাবেলার সর্বোত্তম উপায় হল সরঞ্জাম এবং আর্কিটেকচারাল সিদ্ধান্তের মাধ্যমে উন্নয়নের সময় এগুলি প্রতিরোধ করা।
StrictMode সক্ষম নীতি detectNetwork() এবং detectDiskReads()/detectDiskWrites() সহ উন্নয়নের সময় সম্ভাব্য ANR চিহ্নিত করে। Debug বিল্ডে penaltyDeath সেট করুন — যেকোনো লঙ্ঘন তাত্ক্ষণিক ক্র্যাশ ঘটাবে এবং ডেভেলপার কমিটের আগে সমস্যাটি দেখতে পাবেন।
Firebase Performance মূল অপারেশনের এক্সিকিউশন সময় ট্র্যাক করে এবং দেখায় কোন পরিস্থিতি ANR সীমা অতিক্রম করে। প্রতিটি স্ক্রিন এবং নেটওয়ার্ক অনুরোধের জন্য কাস্টম ট্রেস সেট করুন। যদি এক্সিকিউশন সময় 3 সেকেন্ডের বেশি হয় — এটি একটি সম্ভাব্য ANR যা অপ্টিমাইজেশন প্রয়োজন।
ধীর অবস্থার অনুকরণ করুন: iOS বা Android Emulator এ Network Link Conditioner ব্যবহার করে নেটওয়ার্ক গতি সীমিত করুন। ধীর মেমরির অনুকরণের মাধ্যমে ডিস্ক পড়া ধীর করুন। ANR প্রায়শই এই ধরনের অবস্থাতেই প্রকাশ পায়, দ্রুত ডেভেলপার ডিভাইসে এগুলি দেখা যায় না।
সচরাচর জিজ্ঞাসা
Android প্রধান থ্রেডে ইভেন্ট প্রসেসিং সময় স্পষ্টভাবে ট্র্যাক করে এবং ANR ডায়ালগ দেখায়। iOS Watchdog ব্যবহার করে, যা 10–20 সেকেন্ডের বেশি হ্যাং হলে অ্যাপটি জোর করে বন্ধ করে দেয়। ANR Android আর্কিটেকচারের একটি বৈশিষ্ট্য যেখানে একাধিক উপাদানের (BroadcastReceiver, Service) কঠোর টাইমআউট রয়েছে।
Android 11+ এ আপনি adb shell dumpsys dropbox --print data_app_anr এর মাধ্যমে ANR ডাম্প পেতে পারেন। Android 10 এবং নিচে, /data/anr/traces.txt এ রুট অ্যাক্সেস ছাড়া প্রবেশ করা যায় না। Firebase Crashlytics ব্যবহার করুন — এটি Android 11+ এর জন্য স্বয়ংক্রিয়ভাবে ANR রিপোর্ট সংগ্রহ করে।
Google Play ANR রেট 0.5% এর কম সুপারিশ করে — প্রতি 1000 সেশনে 5টির বেশি ANR নয়। 1% এর বেশি রেটযুক্ত অ্যাপ Google Play Console এ সতর্কতা পায় এবং সুপারিশ থেকে লুকানো হতে পারে। আদর্শভাবে, ANR রেট 0.1% এর নিচে হওয়া উচিত।
করুটিন নিজে থ্রেড ব্লক করে না। কিন্তু করুটিনের ভিতরে যদি আপনি প্রধান থ্রেডে runBlocking চালান বা করুটিন Dispatchers.Main দিয়ে চালু হয় এবং দীর্ঘ CPU অপারেশন করে — এটি ANR ঘটাবে। I/O এর জন্য Dispatchers.IO এবং গণনার জন্য Dispatchers.Default ব্যবহার করুন।
“Slow Network” প্রোফাইল সহ Android Emulator ব্যবহার করুন বা একটি পরীক্ষা লিখুন যা প্রধান থ্রেডে Thread.sleep(6000) কল করে। Debug এর মাধ্যমে অ্যাপ চালু করুন এবং 5 সেকেন্ড পরে আপনি ANR ডায়ালগ দেখতে পাবেন। logcat এ ট্রেস সহ ANR রেকর্ড আছে কিনা পরীক্ষা করুন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন