প্রতিক্রিয়াহীন থ্রেড খুঁজুন

এই ডকুমেন্টটি দেখায় কিভাবে একটি ANR স্ট্যাক ডাম্পে প্রতিক্রিয়াশীল থ্রেড সনাক্ত করতে হয়। প্রতিক্রিয়াহীন থ্রেড ANR-এর ধরন অনুসারে পরিবর্তিত হয়, যেমনটি নিম্নলিখিত টেবিলে দেখানো হয়েছে।

ANR প্রকার প্রতিক্রিয়াহীন থ্রেড
ইনপুট প্রেরণ প্রধান থ্রেড
ইনপুট প্রেরণ কোন ফোকাস উইন্ডো প্রধান থ্রেড। এই ধরনের ANR সাধারণত ব্লক করা থ্রেডের কারণে হয় না।
ব্রডকাস্ট রিসিভার (সিঙ্ক্রোনাস) থ্রেড onReceive() চলছে। এটি হল প্রধান থ্রেড যদি না একটি অ-প্রধান থ্রেডের একটি কাস্টম হ্যান্ডলার Context.registerReceiver ব্যবহার করে নির্দিষ্ট করা হয়।
ব্রডকাস্ট রিসিভার (অসিঙ্ক্রোনাস) goAsync কল করার পরে সম্প্রচার প্রক্রিয়া করার জন্য কোন থ্রেড বা থ্রেড পুলটি কাজ করার জন্য দায়ী তা দেখতে কোডটি পরীক্ষা করুন৷
পরিষেবার সময়সীমা কার্যকর করা হচ্ছে প্রধান থ্রেড
ফোরগ্রাউন্ড পরিষেবা শুরু প্রধান থ্রেড
কন্টেন্ট প্রদানকারী সাড়া দিচ্ছে না হয়:
  • বাইন্ডার থ্রেড যদি ANR ধীরগতির কন্টেন্ট প্রদানকারীর প্রশ্নের কারণে হয়।
  • একটি দীর্ঘ অ্যাপ স্টার্টআপের কারণে ANR হলে মূল থ্রেড।
onStartJob বা onStopJob এর কোনো প্রতিক্রিয়া নেই প্রধান থ্রেড

কখনও কখনও একটি ভিন্ন থ্রেড বা প্রক্রিয়ার মূল কারণের কারণে থ্রেডটি প্রতিক্রিয়াশীল নয়। নিম্নলিখিত অপেক্ষা করার কারণে থ্রেডটি প্রতিক্রিয়াহীন হতে পারে:

  • একটি ভিন্ন থ্রেড দ্বারা রাখা একটি তালা.
  • একটি ভিন্ন প্রক্রিয়া একটি ধীর বাইন্ডার কল.

প্রতিক্রিয়াহীন থ্রেডের সাধারণ কারণ

নিম্নোক্ত প্রতিক্রিয়াহীন থ্রেডের সাধারণ কারণ।

ধীর বাইন্ডার কল

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

আপনি যেখানেই সম্ভব ব্যাকগ্রাউন্ড থ্রেডে সিঙ্ক্রোনাস বাইন্ডার কলগুলি সরানোর মাধ্যমে এটি সমাধান করতে পারেন। যদি কলটি মূল থ্রেডে হতেই হয়, তাহলে কলটি ধীরগতির কেন তা খুঁজে বের করুন। এটি করার সেরা উপায় হল Perfetto ট্রেস থেকে।

স্ট্যাকগুলিতে BinderProxy.transactNative বা Binderproxy.transact সন্ধান করুন৷ এর মানে একটি বাইন্ডার কল হচ্ছে। এই দুটি লাইন অনুসরণ করে, আপনি বাইন্ডার API দেখতে পারেন যা বলা হয়। নিম্নলিখিত উদাহরণে, IAccessibilityManager.addClient কে কল করা হয়েছে।

main tid=123

...
android.os.BinderProxy.transactNative (Native method)
android.os.BinderProxy.transact (BinderProxy.java:568)
android.view.accessibility.IAccessibilityManager$Stub$Proxy.addClient (IAccessibilityManager.java:599)
...

পরপর অনেক বাইন্ডার কল

একটি টাইট লুপে অনেকগুলো পরপর বাইন্ডার কল করা দীর্ঘ সময়ের জন্য একটি থ্রেড ব্লক করতে পারে।

একটি ব্লকিং I/O

প্রধান থ্রেডে I/O ব্লক করা কখনই করবেন না। এটি একটি অ্যান্টিপ্যাটার্ন।

লক বিরোধ

একটি লক অর্জন করার সময় একটি থ্রেড ব্লক করা হলে, এটি একটি ANR হতে পারে।

নিম্নলিখিত উদাহরণ দেখায় একটি লক অর্জন করার চেষ্টা করার সময় প্রধান থ্রেড ব্লক করা হয়েছে:

main (tid=1) Blocked

Waiting for com.example.android.apps.foo.BarCache (0x07d657b7) held by
ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD
[...]
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5412)
[...]

ব্লকিং থ্রেড একটি ভিডিও ডাউনলোড করার জন্য একটি HTTP অনুরোধ করছে:

ptz-rcs-28-EDITOR_REMOTE_VIDEO_DOWNLOAD (tid=110) Waiting

at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:715)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1047)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:230)
at com.example.android.apps.foo.HttpRequest.execute(HttpRequest:136)
at com.example.android.apps.foo$Task$VideoLoadTask.downloadVideoToFile(RequestExecutor:711)
[...]

ব্যয়বহুল ফ্রেম

একটি একক ফ্রেমে অনেকগুলি জিনিস রেন্ডার করার ফলে প্রধান থ্রেড ফ্রেমের সময়কালের জন্য প্রতিক্রিয়াহীন হতে পারে, যেমন নিম্নলিখিতগুলি:

  • অনেক অপ্রয়োজনীয় অফ-স্ক্রিন আইটেম রেন্ডারিং।
  • অনেক UI উপাদান রেন্ডার করার সময় একটি অদক্ষ অ্যালগরিদম ব্যবহার করা, যেমন O(n^2)

অন্যান্য উপাদান দ্বারা অবরুদ্ধ

যদি অন্য একটি উপাদান, যেমন একটি ব্রডকাস্ট রিসিভার, মূল থ্রেডটিকে পাঁচ সেকেন্ডের বেশি সময় ধরে ব্লক করে, তাহলে এটি ইনপুট প্রেরণ ANR এবং গুরুতর জ্যাঙ্কের কারণ হতে পারে।

অ্যাপের উপাদানগুলির প্রধান থ্রেডে কোনও ভারী কাজ করা এড়িয়ে চলুন। যেখানেই সম্ভব একটি ভিন্ন থ্রেডে সম্প্রচার রিসিভার চালান।