'Thread.UncaughtExceptionHandler'에 해당되는 글 1건

  1. 2013.05.14 [안드로이드] Thread.UncaughtExceptionHandler 사용팁 1

최근에 안드로이드에서 글로벌한 방법으로 에러를 처리하는 방법에는 어떤 것이 있는지 찾아보다가 우연히 java.lang.Thread.UncaughtExceptionHandler 인터페이스에 대해서 알게됐습니다. 


Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); 


public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {

        @Override

        public void uncaughtException(Thread thread, final Throwable ex) {

           // 여기서 에러를 처리

        }

}


위와 같은 코드를 통해서 캐치되지 않은 런타임 exception을 일관된 방식으로 한곳에서 처리할 수 있도록 JDK 5.0부터 추가된 것이더군요.


안드로이드에서도 위 방법을 사용하는 것이 가능한데요, UncaughtExceptionHandler 구현시 도움이 될만한 팁을 공유합니다.


1. uncaughtException() 메소드의 맨 마지막에는 반드시 System.exit()를 호출해야 한다. 

그렇지 않으면 앱은 죽은 것도 아니고 작동하는 것도 아닌 불확실한 상태가 됩니다(백그라운드 쓰레드에서 던져진 exception인 경우에는 예외???).


http://stackoverflow.com/questions/13416879/show-a-dialog-in-thread-setdefaultuncaughtexceptionhandler

http://stackoverflow.com/questions/11281182/setdefaultuncaughtexceptionhandler-makes-app-crash-silently


참고로, ACRA의 경우에는 아래와 같은 코드를 사용하고 있습니다.


android.os.Process.killProcess(android.os.Process.myPid());

System.exit(10);



2. Toast를 띄우려면 명시적으로 UI쓰레드에서 띄워야 한다. 

그리고 사용자가 토스트 메시지를 읽을 수 있게 잠깐 쓰레드를 쉬는 것이 좋습니다.


http://stackoverflow.com/questions/11609640/toast-not-showing-up-in-uncaughtexceptionhandler


new Thread() {

@Override

public void run() {

                // UI쓰레드에서 토스트 뿌림

Looper.prepare();

Toast.makeText(getApplicationContext(), "에러메시지", Toast.LENGTH_SHORT)

.show();

Looper.loop();

}

}.start();


// 쓰레드 잠깐 쉼

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

}


 android.os.Process.killProcess(android.os.Process.myPid());

 System.exit(10);



3. Dialog를 띄우려면 Dialog 테마를 가진 새로운 액티비티를 시작하면 된다.

(잘 안되는 경우 ACRA 소스를 참조. Intent.FLAG_ACTIVITY_NEW_TASK 플래그 추가하여 액티비티 시작). 


http://stackoverflow.com/questions/13416879/show-a-dialog-in-thread-setdefaultuncaughtexceptionhandler

http://lky1001.tistory.com/45


Intent crashedIntent = new Intent(getApplicationContext(), MyErrorMessageDialogActivity.class);

crashedIntent.putExtra("error.message", "에러메시지");

crashedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(crashedIntent);


<activity

android:name=".MyErrorMessageDialogActivity"

android:excludeFromRecents="true"

android:finishOnTaskLaunch="true"

android:launchMode="singleInstance"

android:theme="@android:style/Theme.Dialog" >

</activity>


그런데 Toast 띄우는 것과는 다르게 Dialog 띄우는 것은 exception이 UI 쓰레드에서 던져진 것인지 백그라운드 쓰레드에서 던져진 것인지에 따라 다르게 처리해주어야 할 것으로 보입니다. 

실제로 ACRA 라이브러리의 경우 ReportingInteractionMode.DIALOG 모드로 설정했더라도 백그라운드 쓰레드에서 발생한 에러에 대해서는 dialog가 띄워지지 않았습니다(System.exit() 때문?)


예를들어, UI쓰레드에서 던져진 exception인 경우에는 현재 액티비티를 바로 종료하고, 백그라운드 쓰레드에서 던져진 경우에는 현재 액티비티 화면을 그대로 살려두고 싶다면 아래와 같이 System.exit()를 선택적으로 호출할 수 있습니다.

if (Thread.currentThread() == Looper.getMainLooper().getThread() ) {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}


4. 앱 종료된 후 앱을 자동으로 재시작하고 싶으면 AlarmManager를 이용한다.

http://www.kmshack.kr/277#.UZCNP4Ez3E0

http://stackoverflow.com/questions/8943288/how-to-implement-uncaughtexception-android




Posted by 에코지오
,