본문 바로가기

안드로이드 개발/Native

UncaughtExceptionHandler를 이용한 앱 비정상 종료시 Log전송 및 재실행 하기

반응형

UncaughtExceptionHandler를 이용한 앱 비정상 종료시 Log전송 및 재실행 하기



요즘 앱을 보면 앱실행중 Exception이 발생하면 앱이 종료 되었다가 재 실행 되는것을 볼 수 있다. 어떻게 앱이 비정상 종료되는 순간을 Catch한것일까?

 

방법은 UncaughtExceptionHandler를 이용하면 된다.



보통 Thread는 try{} catch(Exception e){}외에 발생 하는 예외는 UncaughtExceptionHandler의 uncaughtThread(Thead thread, Throwable ex)를 호출 하게 되어 있다. 그래서 Thread의 UncaughtExceptionHandler 인스턴스를 Thread에 등록하면 되는데, Thread의 static메소드인 setDefaultUncaughtExceptionHandler()를 이용하여 UncaughtExceptionHandler를 set할 수 있다. 



이렇게 하면 별도로 예외처리 하지 않은 부분에서 예외가 발생 하게되면 uncaughtThread(Thead thread, Throwable ex)가 호출되어 유용한 작업들을 할 수있다.


그럼 간략하게 구현 해보자.


import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;

import android.app.Application;
import android.util.Log;

public class MyApplication extends Application {
	
	private UncaughtExceptionHandler mUncaughtExceptionHandler;
	
	@Override
	public void onCreate(){

		mUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerApplication());
		
		super.onCreate();
	}
	
	/**
	 * 메시지로 변환
	 * @param th
	 * @return
	 */
    private String getStackTrace(Throwable th) {

        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);

        Throwable cause = th;
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        final String stacktraceAsString = result.toString();
        printWriter.close();

        return stacktraceAsString;
    }
	
	class UncaughtExceptionHandlerApplication implements Thread.UncaughtExceptionHandler{

		@Override
		public void uncaughtException(Thread thread, Throwable ex) {
			
			//예외상황이 발행 되는 경우 작업
			Log.e("Error", getStackTrace(ex)); 
			
			//예외처리를 하지 않고 DefaultUncaughtException으로 넘긴다.
			mUncaughtExceptionHandler.uncaughtException(thread, ex);
		}
		
	}
}


안드로이드에서 Application onCreate()에서 Thread.setDefaultUncaughtExceptionHandler를 구현해주면 끝이다.


예외 상황 발생시 AlarmManager로 앱을 재 실행 하던가, 로그를 저장해두었다가 앱이 재 실행 되면 서버로 전송하는 기능을 구현하면 될 듯 하다.

실제로 ACRA이라는 버그리포팅 해주는 라이브러리가 이런 방법으로 구현 되어 있다. 


레퍼런스도 참고 하기 바란다.

http://developer.android.com/reference/java/lang/Thread.UncaughtExceptionHandler.html






반응형