IT TIP

Android에서 전역 예외 처리 사용

itqueen 2020. 12. 29. 08:10
반응형

Android에서 전역 예외 처리 사용


코드 예제 또는 Thread.setDefaultUncaughtExceptionHandler메서드 사용 방법에 대한 자습서가 있습니까? 기본적으로 내 응용 프로그램에서 예외가 발생할 때마다 사용자 지정 경고 대화 상자를 표시하려고합니다. 이것이 가능합니까? UI 스레드에서 예외가 발생하면 화면에 무언가를 표시하는 것이 약간 까다 롭다는 것을 알고 있지만 이에 대한 해결 방법을 모릅니다.


이 페이지에 솔루션을 제공하는 사람을위한 기본 예 :)

public class ChildActivity extends BaseActivity {
    @SuppressWarnings("unused")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int a=1/0;
    }
}

오류 처리를위한 클래스 :

public class BaseActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                Log.e("Alert","Lets See if it Works !!!");
            }
        });
    }
}

다음 Mohit Sharma 가 다음과 같이 개선 한 답변 의 변형입니다 .

  • 오류 처리 후 앱 / 서비스가 중단되지 않습니다.
  • Android가 자체적으로 정상적인 오류 처리를 수행하도록합니다.

암호:

public class BaseActivity extends Activity {
    @Override
    public void onCreate() {
        super.onCreate();

        final Thread.UncaughtExceptionHandler oldHandler =
            Thread.getDefaultUncaughtExceptionHandler();

        Thread.setDefaultUncaughtExceptionHandler(
            new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(
                    Thread paramThread,
                    Throwable paramThrowable
                ) {
                    //Do your own error handling here

                    if (oldHandler != null)
                        oldHandler.uncaughtException(
                            paramThread,
                            paramThrowable
                        ); //Delegates to Android's error handling
                    else
                        System.exit(2); //Prevents the service/app from freezing
                }
            });
    }
}

가 있다는 사실을 숙지 The RuntimePermission("setDefaultUncaughtExceptionHandler")핸들러를 설정하기 전에 확인하고 당신이 상황이 불확실한 상태에있을 수 있기 때문에 프로세스가, 캐치되지 않는 예외를 던져, 이후이 중단 될 수 있도록한다.

아무것도 표시하지 마십시오. 실제로 UI 스레드가 충돌했을 수 있습니다. 대신 로그를 작성하거나 세부 정보를 서버에 보냅니다. 이 질문과 대답 을 확인하고 싶을 입니다.


이 라이브러리를 사용하려면

https://github.com/selimtoksal/Android-Caught-Global-Exception-Library

모든 활동이 아니라 기본 활동에서 사용하는 TransferObject를 만듭니다.


I just wanted to point out my experience so far. I am using the solution suggested by https://stackoverflow.com/a/26560727/2737240 to flush the exception into my log file before giving control to the default exception handler.

However, my structure looks like this:

          BaseActivity
               |
    _______________________
    |          |          |
Activity A Activity B Activity C
final Thread.UncaughtExceptionHandler defaultEH = Thread.getDefaultUncaughtExceptionHandler();                                                                                                                                                                                                                                                                                                                              
    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {                                                                                                                                                                                                                                                                                                                                           
        @Override                                                                                                                                                                                                                                                                                                                                                                                                               
        public void uncaughtException(Thread thread, Throwable e) {                                                                                                                                                                                                                                                                                                                                                             
            handleUncaughtException(thread, e, defaultEH);                                                                                                                                                                                                                                                                                                                                                                      
        }                                                                                                                                                                                                                                                                                                                                                                                                                       
 });

where handleUncaughtException(thread, e, defaultEH); writes to the log and hands the call over to the original UncaughtExceptionHandler.

So what happened by using this code was the following:

  • Activity A is instantiated
  • New Default Exception Handler (DEH) is now my log handler + the old DEH
  • Activity B is instantiated
  • New DEH is now my log handler + the old DEH (log handler + original DEH)
  • Activity C is instantiated
  • New DEH is now my log handler + the old DEH (log handler + log handler + original DEH)

So it's a chain growing infinitely causing two problems:

  1. The specified custom code (in my case writing to the log file) will be called multiple times, which is not the desired action.
  2. The reference of defaultEh is kept in the heap even after the activity has been finished, because it is used by the reference chain so the worst thing that could happen is an out of memory exception.

Therefore I added one more thing to finally make this work without issues:

private static boolean customExceptionHandlerAttached = false;                                                                                                                                                                                                                                                                                                                                                                      

@Override                                                                                                                                                                                                                                                                                                                                                                                                                           
protected void onCreate(@Nullable Bundle savedInstanceState) {                                                                                                                                                                                                                                                                                                                                                                      
    super.onCreate(savedInstanceState);                                                                                                                                                                                                                                                                                                                                                                                             

    if(!customExceptionHandlerAttached) {                                                                                                                                                                                                                                                                                                                                                                                            
        final Thread.UncaughtExceptionHandler defaultEH = Thread.getDefaultUncaughtExceptionHandler();                                                                                                                                                                                                                                                                                                                              
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {                                                                                                                                                                                                                                                                                                                                           
            @Override                                                                                                                                                                                                                                                                                                                                                                                                               
            public void uncaughtException(Thread thread, Throwable e) {                                                                                                                                                                                                                                                                                                                                                             
                 handleUncaughtException(thread, e, defaultEH);                                                                                                                                                                                                                                                                                                                                                                      
            }                                                                                                                                                                                                                                                                                                                                                                                                                       
        });                                                                                                                                                                                                                                                                                                                                                                                                                         
        customExceptionHandlerAttached = true;                                                                                                                                                                                                                                                                                                                                                                                      
    }                                                                                                                                                                                                                                                                                                                                                                                                                               
}

With this solution we can make sure to:

  • add a custom exception handler for our desired action
  • ensure that this action is only triggered once
  • allowing garbage collector to dispose our activity completely by calling finish()

ReferenceURL : https://stackoverflow.com/questions/4427515/using-global-exception-handling-on-android

반응형