আমি অ্যান্ড্রয়েড ক্র্যাশগুলির কাস্টম হ্যান্ডলিংয়ের সহজ সমাধান পোস্ট করেছি । এটি সামান্য হ্যাকি তবে এটি সমস্ত অ্যান্ড্রয়েড সংস্করণে (ললিপপ সহ) কাজ করে।
প্রথমে কিছুটা তত্ত্ব। অ্যান্ড্রয়েডে অপ্রকাশিত ব্যতিক্রম হ্যান্ডলারটি ব্যবহার করার সময় মূল সমস্যাগুলি মূল (ওরফে ইউআই) থ্রেডে ফেলে দেওয়া ব্যতিক্রমগুলি নিয়ে আসে। এবং এখানে কেন। যখন অ্যাপ্লিকেশন সিস্টেমটি অ্যাক্টিভিটিথ্রেড.মাইন পদ্ধতিতে কল করে যা আপনার অ্যাপ্লিকেশনটির মূল লুপ প্রস্তুত করে এবং শুরু করে :
public static void main(String[] args) {
…
…
Looper.prepareMainLooper();
…
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
মেইন লুপার ইউআই থ্রেডে পোস্ট হওয়া বার্তাগুলি (ইউআই রেন্ডারিং এবং ইন্টারঅ্যাকশন সম্পর্কিত সমস্ত বার্তা সহ) প্রক্রিয়াকরণের জন্য দায়বদ্ধ। যদি ইউআই থ্রেডে কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয় তবে এটি আপনার ব্যতিক্রম হ্যান্ডলার দ্বারা ধরা পড়বে, তবে আপনি loop()
পদ্ধতি ছাড়ার কারণে আপনি কোনও সংলাপ বা ক্রিয়াকলাপ প্রদর্শন করতে পারবেন না কারণ ইউআই বার্তাগুলি প্রক্রিয়া করার মতো কেউ নেই left তোমার জন্য.
প্রস্তাবিত সমাধানটি বেশ সহজ। আমরা Looper.loop
আমাদের নিজস্ব পদ্ধতি চালাই এবং চেষ্টা-ব্লক দিয়ে এটিকে ঘিরে। কোনও ব্যতিক্রম ধরা পড়লে আমরা যেমনটি চাই তেমন প্রক্রিয়া করি (উদাহরণস্বরূপ আমাদের কাস্টম প্রতিবেদনের ক্রিয়াকলাপ শুরু করুন) এবং Looper.loop
আবার কল পদ্ধতিতে।
নিম্নলিখিত পদ্ধতিটি এই কৌশলটি দেখায় (এটি Application.onCreate
শ্রোতার কাছ থেকে কল করা উচিত ):
private void startCatcher() {
UncaughtExceptionHandler systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler(new Handler()));
while (true) {
try {
Looper.loop();
Thread.setDefaultUncaughtExceptionHandler(systemUncaughtHandler);
throw new RuntimeException("Main thread loop unexpectedly exited");
} catch (Throwable e) {
showCrashDisplayActivity(e);
}
}
}
আপনি দেখতে পাচ্ছেন যে অনাবৃত ব্যতিক্রম হ্যান্ডলারটি কেবল ব্যাকগ্রাউন্ড থ্রেডে ফেলে দেওয়া ব্যতিক্রমগুলির জন্য ব্যবহৃত হয়। নিম্নলিখিত হ্যান্ডলার সেই ব্যতিক্রমগুলি ধরে এবং তাদের ইউআই থ্রেডে প্রচার করে:
static class UncaughtHandler implements UncaughtExceptionHandler {
private final Handler mHandler;
UncaughtHandler(Handler handler) {
mHandler = handler;
}
public void uncaughtException(Thread thread, final Throwable e) {
mHandler.post(new Runnable() {
public void run() {
throw new BackgroundException(e);
}
});
}
}
এই কৌশলটি ব্যবহার করে এমন একটি প্রকল্প যা আমার গিটহাব রেপোতে উপলব্ধ: https://github.com/idolon-github/android-crash-catcher