오래 전에 Android 충돌을 사용자 지정 처리하기위한 간단한 솔루션 을 게시했습니다 . 약간 해키하지만 모든 Android 버전 (Lollipop 포함)에서 작동합니다.
먼저 약간의 이론. Android에서 포착되지 않은 예외 처리기를 사용할 때의 주요 문제는 기본 (일명 UI) 스레드에서 발생한 예외와 함께 발생합니다. 그리고 여기에 그 이유가 있습니다. 앱이 시작되면 시스템이 앱 의 Main looper 를 준비하고 시작하는 ActivityThread.main 메서드를 호출 합니다.
public static void main(String[] args) {
…
…
Looper.prepareMainLooper();
…
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
메인 루퍼는 UI 스레드에 게시 된 메시지 (UI 렌더링 및 상호 작용과 관련된 모든 메시지 포함)를 처리합니다. UI 스레드에서 예외가 발생하면 예외 처리기에 의해 포착되지만 loop()
메서드를 벗어 났으므로 UI 메시지를 처리 할 사람이 남아 있지 않으므로 사용자에게 대화 나 활동을 표시 할 수 없습니다. 당신을 위해.
제안 된 솔루션은 매우 간단합니다. Looper.loop
자체적으로 메소드를 실행 하고 try-catch 블록으로 둘러 쌉니다. 예외가 발견되면 원하는대로 처리하고 (예 : 사용자 지정 보고서 활동 시작) 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);
}
}
}
보시다시피 포착되지 않은 예외 처리기는 백그라운드 스레드에서 발생한 예외에만 사용됩니다. 다음 핸들러는 이러한 예외를 포착하여 UI 스레드로 전파합니다.
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);
}
});
}
}
이 기술을 사용하는 예제 프로젝트는 내 GitHub 저장소에서 사용할 수 있습니다. https://github.com/idolon-github/android-crash-catcher