ANRগুলি

কোনও Android অ্যাপের UI থ্রেড অনেকক্ষণ ধরে ব্লক হয়ে থাকলে, "অ্যাপ্লিকেশন সাড়া দিচ্ছে না" (ANR) সমস্যা ট্রিগার হয়। Android Vitals, Google Play Console-এ ANR মেট্রিক ট্র্যাক করে এবং রিপোর্ট করে যাতে আপনি বিভিন্ন ডিভাইস জুড়ে আপনার অ্যাপের স্থায়িত্ব এবং প্রতিক্রিয়াশীলতা নিরীক্ষণ করতে পারেন।

Android Vitals মেট্রিক ও থ্রেশহোল্ড

Android Vitals আপনার অ্যাপের ANR রেট মনিটর ও উন্নত করতে সাহায্য করতে পারে। Android vitals একাধিক ANR রেট পরিমাপ করে:

  • ANR রেট: আপনার দৈনিক অ্যাক্টিভ ব্যবহারকারীদের শতকরা হার যারা যেকোনও ধরনের ANR-এর অভিজ্ঞতা পেয়েছেন।
  • ব্যবহারকারীর-লক্ষ্য করা ANR রেট: আপনার দৈনিক অ্যাক্টিভ ব্যবহারকারীদের শতকরা হার যারা অন্তত একটি ব্যবহারকারীর-লক্ষ্য করা ANR-এর অভিজ্ঞতা পেয়েছেন। বর্তমানে শুধুমাত্র Input dispatching timed out ধরনের ANR-কে ব্যবহারকারীর-অনুভূত হিসেবে বিবেচনা করা হয়।
  • একাধিক ANR রেট: আপনার দৈনিক অ্যাক্টিভ ব্যবহারকারীদের শতকরা হার যারা অন্তত দুটি ANR-এর অভিজ্ঞতা পেয়েছেন।

দৈনিক অ্যাক্টিভ ব্যবহারকারী হলেন একজন অনন্য ব্যবহারকারী যিনি একটি ডিভাইসে একদিনে আপনার অ্যাপ ব্যবহার করেন, সম্ভবত একাধিক সেশন জুড়ে। কোনও ব্যবহারকারী একদিনে একাধিক ডিভাইসে আপনার অ্যাপ ব্যবহার করলে, প্রতিটি ডিভাইস সেই দিনের অ্যাক্টিভ ব্যবহারকারীর সংখ্যায় যোগ করা হবে।

ব্যবহারকারীর-অনুভূত ANR রেট হল একটি গুরুত্বপূর্ণ ডেটা, যার অর্থ হল এটি Google Play-তে আপনার অ্যাপের খুঁজে পাওয়ার যোগ্যতাকে প্রভাবিত করে। এটি গুরুত্বপূর্ণ কারণ এটি যে ANR গণনা করে তা সবসময় ব্যবহারকারী অ্যাপে এনগেজ থাকার সময় ঘটে, যার ফলে সবচেয়ে বেশি বিঘ্ন ঘটে।

Play এই মেট্রিকের উপর দুটি খারাপ পারফর্ম্যান্স থ্রেশহোল্ড নির্ধারণ করেছে:

  • সামগ্রিকভাবে খারাপ পারফর্ম্যান্স থ্রেশহোল্ড: সব ডিভাইস মডেল জুড়ে দৈনিক অ্যাক্টিভ ব্যবহারকারীদের মধ্যে কমপক্ষে ০.৪৭% ব্যবহারকারী ব্যবহারকারীর-লক্ষ্য করা ANR-এর অভিজ্ঞতা পান।
  • প্রতি-ডিভাইস খারাপ পারফর্ম্যান্স থ্রেশহোল্ড: দৈনিক ব্যবহারকারীদের মধ্যে অন্তত ৮% ব্যবহারকারী ব্যবহারকারীর-লক্ষ্য করা ANR-এর অভিজ্ঞতা পান, একটি ডিভাইস মডেলের জন্য।

আপনার অ্যাপ যদি সামগ্রিক খারাপ পারফর্ম্যান্স থ্রেশহোল্ড অতিক্রম করে, তাহলে সব ডিভাইসে এটি খুঁজে পাওয়ার সম্ভাবনা কমে যেতে পারে। আপনার অ্যাপ কিছু ডিভাইসে প্রতি-ডিভাইস খারাপ পারফর্ম্যান্স থ্রেশহোল্ড ছাড়িয়ে গেলে, সেইসব ডিভাইসে এটি খুঁজে পাওয়ার সম্ভাবনা কম এবং আপনার স্টোর লিস্টিংয়ে একটি সতর্কতা দেখানো হতে পারে।

আপনার অ্যাপে অত্যধিক ANR হলে, Android Vitals আপনাকে Play Console-এর মাধ্যমে সতর্ক করতে পারে।

Google Play কীভাবে Android Vitals ডেটা সংগ্রহ করে সেই সম্পর্কে তথ্য পেতে, Play Console ডকুমেন্টেশন দেখুন।

সমস্যা শনাক্ত করা

ANR হওয়ার সময় অ্যাপটি ফোরগ্রাউন্ডে থাকলে, সিস্টেম ব্যবহারকারীকে একটি ডায়ালগ দেখায়, যেমনটি চিত্র ১-এ দেখানো হয়েছে। ANR ডায়ালগ ব্যবহারকারীকে অ্যাপটি জোর করে বন্ধ করার সুযোগ দেয়।

ব্যবহারকারীকে ANR ডায়ালগ দেখানো হয়েছে।
ছবি ১. ব্যবহারকারীকে ANR ডায়ালগ দেখানো হয়েছে

ANR একটি সমস্যা কারণ অ্যাপের প্রধান থ্রেড, যা UI আপডেট করার জন্য দায়ী, ব্যবহারকারীর ইনপুট ইভেন্ট বা ড্র প্রসেস করতে পারে না, যার ফলে ব্যবহারকারী হতাশ হন। অ্যাপের মূল থ্রেড সম্পর্কে আরও তথ্যের জন্য, প্রসেস এবং থ্রেড ওভারভিউ দেখুন।

নিম্নলিখিত কোনও একটি পরিস্থিতি দেখা দিলে আপনার অ্যাপের জন্য ANR ট্রিগার করা হয়:

  • ইনপুট ডিসপ্যাচ করার সময়সীমা শেষ হয়ে গেছে: আপনার অ্যাপ ৫ সেকেন্ডের মধ্যে কোনও ইনপুট ইভেন্টের (যেমন, কোনও কী প্রেস করা বা স্ক্রিন টাচ করা) উত্তর না দিলে।
  • পরিষেবা এক্সিকিউট করা: আপনার অ্যাপের মাধ্যমে ঘোষিত কোনও পরিষেবা যদি Service.onCreate এবং Service.onStartCommand অথবা Service.onBind কয়েক সেকেন্ডের মধ্যে এক্সিকিউট করা শেষ করতে না পারে।
  • Service.startForeground কল করা হয়নি: আপনার অ্যাপ যদি Context.startForegroundService ব্যবহার করে ফোরগ্রাউন্ডে নতুন পরিষেবা শুরু করে কিন্তু পরিষেবাটি ৫ সেকেন্ডের মধ্যে startForeground কল না করে।
  • উদ্দেশ্যের ব্রডকাস্ট: যদি একটি BroadcastReceiver নির্দিষ্ট সময়ের মধ্যে সম্পূর্ণ না হয়। অ্যাপের কোনও অ্যাক্টিভিটি ফোরগ্রাউন্ডে থাকলে, এই টাইমআউট ১০ সেকেন্ডের হয়।
  • JobScheduler ইন্টার‍্যাকশন: যদি JobService কয়েক সেকেন্ডের মধ্যে JobService.onStartJob বা JobService.onStopJob থেকে ফিরে না আসে, অথবা যদি কোনও ব্যবহারকারীর শুরু করা কাজ শুরু হয় এবং আপনার অ্যাপ JobService.onStartJob কল করার কয়েক সেকেন্ডের মধ্যে JobService.setNotification কল না করে। Android 13 এবং তার আগের ভার্সনকে টার্গেট করা অ্যাপের ক্ষেত্রে, ANR সাইলেন্ট থাকে এবং অ্যাপে রিপোর্ট করা হয় না। Android 14 এবং তার পরের ভার্সনকে টার্গেট করা অ্যাপের ক্ষেত্রে, ANR এক্সপ্লিসিট থাকে এবং অ্যাপে রিপোর্ট করা হয়।

Android Vitals ছাড়াও, আপনি ফিল্ডে ANR শনাক্ত করার জন্য অন্যান্য টুল ব্যবহার করতে পারেন, যদিও থার্ড-পার্টি টুল Android 10 (API লেভেল ২৯) এবং তার নিচের ভার্সনে ANR রিপোর্ট করতে পারে না।

ANR ডায়াগনসিস করা

ANR ডায়াগনসিস করার সময় কিছু সাধারণ প্যাটার্ন লক্ষ্য করতে হয়:

  • অ্যাপটি মূল থ্রেডে I/O সহ ধীর অপারেশন করছে।
  • অ্যাপটি মূল থ্রেডে দীর্ঘ গণনা করছে।
  • মূল থ্রেড অন্য একটি প্রসেসে সিঙ্ক্রোনাস বাইন্ডার কল করছে এবং সেই অন্য প্রসেসটি ফিরে আসতে অনেক সময় নিচ্ছে।
  • অন্য থ্রেডে চলা দীর্ঘ অপারেশনের জন্য সিঙ্ক্রোনাইজ করা ব্লকের অপেক্ষায় মূল থ্রেডটি ব্লক করা হয়েছে।
  • আপনার প্রসেসে বা বাইন্ডার কলের মাধ্যমে মেইন থ্রেড অন্য থ্রেডের সাথে ডেডলক হয়ে গেছে। মূল থ্রেডটি শুধু দীর্ঘ অপারেশন শেষ হওয়ার জন্য অপেক্ষা করছে না, বরং এটি একটি ডেডলক পরিস্থিতিতে রয়েছে।

নিম্নলিখিত কৌশলগুলি আপনাকে ANR-এর কারণ নির্ধারণ করতে সাহায্য করতে পারে।

HealthStats

HealthStats মোট ব্যবহারকারী এবং সিস্টেমের সময়, সিপিইউ টাইম, নেটওয়ার্ক, রেডিও পরিসংখ্যান, স্ক্রিন চালু ও বন্ধ থাকার সময় এবং ওয়েক আপ অ্যালার্ম ক্যাপচার করে অ্যাপ্লিকেশনের স্বাস্থ্য সম্পর্কে মেট্রিক প্রদান করে। এটি আপনাকে সামগ্রিক CPU ব্যবহার ও ব্যাটারি ড্রেনেজ পরিমাপ করতে সাহায্য করতে পারে।

ডিবাগ করুন

Debug আপনাকে ডেভেলপমেন্টের সময় Android অ্যাপ্লিকেশন পরীক্ষা করতে সাহায্য করে, যার মধ্যে অ্যাপে জ্যাঙ্ক ও ল্যাগ শনাক্ত করার জন্য ট্রেসিং ও অ্যালোকেশন কাউন্ট অন্তর্ভুক্ত। এছাড়াও, রানটাইম ও নেটিভ মেমরি কাউন্টার এবং মেমরি মেট্রিক পেতে আপনি Debug ব্যবহার করতে পারেন, যা আপনাকে নির্দিষ্ট কোনও প্রসেসের মেমরি ফুটপ্রিন্ট শনাক্ত করতে সাহায্য করতে পারে।

ApplicationExitInfo

ApplicationExitInfo Android 11 (API লেভেল 30) এবং তার পরবর্তী ভার্সনে উপলভ্য এবং অ্যাপ্লিকেশন থেকে বেরিয়ে আসার কারণ সম্পর্কে তথ্য প্রদান করে। এর মধ্যে ANR, কম মেমরি, অ্যাপ ক্র্যাশ, অত্যধিক CPU ব্যবহার, ব্যবহারকারীর বাধা, সিস্টেমের বাধা এবং রানটাইম অনুমতি পরিবর্তন অন্তর্ভুক্ত।

স্ট্রিক্ট মোড

StrictMode ব্যবহার করলে, অ্যাপ ডেভেলপ করার সময় আপনি প্রধান থ্রেডে আকস্মিক I/O অপারেশন খুঁজে পেতে পারেন। আপনি অ্যাপ্লিকেশন বা অ্যাক্টিভিটি লেভেলে StrictMode ব্যবহার করতে পারেন।

ব্যাকগ্রাউন্ড ANR ডায়ালগ চালু করুন

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

প্রোফাইল সিপিইউ এবং সিস্টেম ট্রেস

আপনার গেম চলাকালীন সিস্টেম ট্রেস এবং CPU অ্যাক্টিভিটি রেকর্ড করতে Android Studio CPU Profiler ব্যবহার করুন। আপনার গেম ইঞ্জিনের রেন্ডার, অডিও এবং ওয়ার্কার থ্রেডের পাশাপাশি প্রধান Activity থ্রেডটি পরীক্ষা করলে, আপনি দীর্ঘ ফ্রেম, সিঙ্ক্রোনাস অ্যাসেট লোড এবং থ্রেড কন্টেনশন ANR ট্রিগার করার আগেই শনাক্ত করতে পারবেন।

ট্রেস ফাইল পুল করুন

ANR-এর অভিজ্ঞতা হলে Android ট্রেস তথ্য স্টোর করে। Android-এর পুরনো ভার্সনে, ডিভাইসে একটিই /data/anr/traces.txt ফাইল থাকে। Android-এর আরও উন্নত ভার্সনে, একাধিক /data/anr/anr_* ফাইল আছে। আপনি রুট হিসেবে Android ডিবাগ ব্রিজ (adb) ব্যবহার করে কোনও ডিভাইস বা এমুলেটর থেকে ANR ট্রেস অ্যাক্সেস করতে পারবেন:

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

আপনি ডিভাইসে 'ত্রুটির রিপোর্ট নিন' ডেভেলপার বিকল্প অথবা আপনার ডেভেলপমেন্ট মেশিনে adb bugreport কমান্ড ব্যবহার করে ফিজিক্যাল ডিভাইস থেকে ত্রুটির রিপোর্ট ক্যাপচার করতে পারবেন। আরও তথ্যের জন্য, ত্রুটির প্রতিবেদন ক্যাপচার করা ও পড়া দেখুন।

সমস্যার সমাধান করা

সমস্যাটি শনাক্ত করার পরে, আপনি এই বিভাগে দেওয়া পরামর্শ ব্যবহার করে সাধারণত দেখা যায় এমন সমস্যার সমাধান করতে পারবেন।

মূল থ্রেডে স্লো কোড

আপনার কোডের সেইসব জায়গা শনাক্ত করুন যেখানে অ্যাপের মূল থ্রেড ৫ সেকেন্ডের বেশি সময় ধরে ব্যস্ত থাকে। আপনার গেমে সন্দেহজনক ব্যবহারের ক্ষেত্রগুলি খুঁজুন এবং ANR পুনরুৎপাদন করার চেষ্টা করুন।

গেমের ক্ষেত্রে, সাধারণত সিঙ্ক্রোনাস অ্যাসেট ডিকম্প্রেশন, শেডার কম্পাইলেশন বা ভারী গেম-স্টেট ইনিশিয়ালাইজেশন Android-এর মূল Activity থ্রেডে (যেমন, onCreate, onResume-এর মধ্যে বা UI থ্রেড থেকে কল করা JNI কলব্যাক) রান করলে, মূল থ্রেড স্টল হয়ে যায়। গেম লুপ এক্সিকিউশন, অ্যাসেট প্রসেসিং এবং দৃশ্য শুরু করার মতো কাজগুলি ডেডিকেটেড ইঞ্জিন, রেন্ডার বা ব্যাকগ্রাউন্ড ওয়ার্কার থ্রেডে সরিয়ে দিন, যাতে মূল থ্রেড ইনপুট এবং লাইফসাইকেল ইভেন্ট প্রসেস করার জন্য ফ্রি থাকে।

মূল থ্রেডে I/O

মূল থ্রেডে I/O অপারেশন এক্সিকিউট করা হল মূল থ্রেডে ধীরগতির অপারেশনের একটি সাধারণ কারণ, যা ANR-এর কারণ হতে পারে।

সব অ্যাসেট বান্ডেল রিড, সেভ-গেম সিরিয়ালাইজেশন, SharedPreferences অ্যাক্সেস ও নেটওয়ার্ক অনুরোধ মূল Activity থ্রেড থেকে ব্যাকগ্রাউন্ড ওয়ার্কার থ্রেডে সরিয়ে দিন যাতে স্টোরেজ বা নেটওয়ার্ক লেটেন্সি ইনপুট ডিসপ্যাচিং ব্লক করতে না পারে।

ডেডলক

ডেডলক তখনই হয় যখন কোনও থ্রেড অপেক্ষারত অবস্থায় চলে যায় কারণ প্রয়োজনীয় রিসোর্স অন্য থ্রেডের কাছে থাকে, যেটি আবার প্রথম থ্রেডের কাছে থাকা রিসোর্সের জন্য অপেক্ষা করছে। অ্যাপের মূল থ্রেড এই পরিস্থিতিতে থাকলে, ANR হওয়ার সম্ভাবনা বেশি।

গেমের ক্ষেত্রে, Android-এর মূল Activity থ্রেড (লাইফসাইকেল, সারফেস বা ইনপুট কলব্যাক ম্যানেজ করা) এবং নেটিভ C বা C++ রেন্ডার, লজিক বা অডিও থ্রেডের মধ্যে ডেডলক ও লক কনটেনশন প্রায়ই ঘটে। নেটিভ ইঞ্জিন লকের জন্য মূল থ্রেডে সিঙ্ক্রোনাস অপেক্ষা এড়িয়ে চলুন এবং JNI এবং ইঞ্জিন থ্রেড জুড়ে যোগাযোগ করার সময় সামঞ্জস্যপূর্ণ লক অর্ডারিং বা লক-মুক্ত মেসেজ কিউ ব্যবহার করুন।

ডেডলক হল কম্পিউটার সায়েন্সের একটি সুপরিচিত ঘটনা এবং ডেডলক প্রতিরোধ করার জন্য অ্যালগরিদম আছে যা আপনি ডেডলক এড়াতে ব্যবহার করতে পারেন।

আরও তথ্যের জন্য, Wikipedia-তে ডেডলক এবং ডেডলক প্রতিরোধ অ্যালগরিদম দেখুন।

ধীরগতির সম্প্রচার রিসিভার

অ্যাপগুলি ব্রডকাস্ট রিসিভারের মাধ্যমে ব্রডকাস্ট মেসেজের উত্তর দিতে পারে, যেমন বিমান মোড চালু বা বন্ধ করা বা কানেক্টিভিটি স্ট্যাটাসে পরিবর্তন করা। ব্রডকাস্ট মেসেজ প্রসেস করতে কোনও অ্যাপ অনেক বেশি সময় নিলে ANR হয়।

নিম্নলিখিত ক্ষেত্রে ANR হয়:

  • একটি ব্রডকাস্ট রিসিভার যথেষ্ট সময়ের মধ্যে তার onReceive পদ্ধতি সম্পূর্ণ করেনি।
  • একটি ব্রডকাস্ট রিসিভার goAsync-কে কল করে এবং PendingResult অবজেক্টে finish-কে কল করতে ব্যর্থ হয়।

আপনার অ্যাপকে BroadcastReceiver-এর onReceive পদ্ধতিতে শুধুমাত্র ছোট অপারেশন সম্পাদন করতে হবে। তবে, ব্রডকাস্ট মেসেজের ফলে আপনার অ্যাপে আরও জটিল প্রসেসিংয়ের প্রয়োজন হলে, টাস্কটি সম্পূর্ণ হতে কয়েক সেকেন্ড সময় লাগলে, আপনাকে ব্যাকগ্রাউন্ড ওয়ার্কার থ্রেডে টাস্কটি পিছিয়ে দিতে হবে অথবা কয়েক সেকেন্ডের বেশি সময় লাগলে, WorkManager-এ টাস্কটি পিছিয়ে দিতে হবে।

GameActivity

C বা C++-এ লেখা গেম ও অ্যাপের কেস স্টাডিতে GameActivity লাইব্রেরি ANR কমিয়েছে। আপনি যদি আগে থেকে থাকা নেটিভ অ্যাক্টিভিটি GameActivity দিয়ে পরিবর্তন করেন, তাহলে UI থ্রেড ব্লক হওয়া কমাতে পারবেন এবং কিছু ANR হওয়া আটকাতে পারবেন।

আপনি Unity-র সাহায্যে গেম তৈরি করলে, Unity গেমের জন্য ANR ডিবাগ করা, সাধারণ Unity গেমের ANR এবং Unity গেমের জন্য Android ক্র্যাশ ও ANR সিম্বল করা দেখুন।

ANR সম্পর্কে আরও তথ্যের জন্য, আপনার অ্যাপ রেসপন্সিভ রাখুন দেখুন। থ্রেড সম্পর্কে আরও তথ্য পেতে, থ্রেডিংয়ের মাধ্যমে আরও ভালো পারফর্ম্যান্স দেখুন।