Android app 이 crash 하 는 이유 및 해결 방법

4788 단어 Androidappcrash
android main 입구 의 comonInit()방법 안에 이런 말 이 있 습 니 다.

Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
이 말 이 없 었 다 면 app 은 crash 하지 않 았 을 것 이다.못 믿 겠 으 면 안 을 들 여 다 봐.

public KillApplicationHandler(LoggingHandler loggingHandler) {
 @Override
 public void uncaughtException(Thread t, Throwable e) {
 //     
   try {
     ......
     //  crash  ,       
     // Bring up crash dialog, wait for it to be dismissed
     ActivityManager.getService().handleApplicationCrash(
       mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
      } catch (Throwable t2) {
        .... 
      } finally {
        // Try everything to make sure this process goes away.
        Process.killProcess(Process.myPid());//    
        System.exit(10);
      }
    }
  } 
이상 KillApplication Handler 가 이상 을 포착 하면 일련의 처리(주로 crash 로 그 를 인쇄 하고 AMS 에 crash 팝 업 창 을 보 여 주 는 것 등)를 한 후에 프로 세 스 를 죽 입 니 다.그러면 app 이 무 너 집 니 다.
무 너 졌 으 니 이상 포획 기 를 사용자 정의 해서 crash 를 차단 할 수 있 습 니까?
시스템 의 KillApplication Handler 를 덮어 쓰 고 이상 을 포착 한 후에 프로 세 스 를 죽 이지 않 으 면 app 이 무 너 지지 않 습 니 다.아래 와 같이...

class MainApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Thread.setDefaultUncaughtExceptionHandler { _, e ->
      //     ,     ,    
      Log.e("MainApplication", "${Thread.currentThread().name}      :${e.message}")
    }
  }
}
이것 은 사실은 옆집 왕 씨 의 생각 일 뿐 입 니 다.비록 서브 스 레 드 의 crash 를 보호 하지만 메 인 스 레 드 에 이상 이 생 겼 을 때 app 은 정상적으로 작 동 하지 못 합 니 다.이 는 UncaughtException Handler 가 스 레 드 에 이상 이 있 을 때 스 레 드 가 uncaughtException()에서 처 리 된 후 더 이상 생존 할 수 없 기 때문이다.이상 한 스 레 드 가 메 인 스 레 드 라면 메 인 스 레 드 가 죽 는 것 을 의미 합 니 다.이 때 프로 세 스 를 죽 이지 않 아 도 프로 세 스 가 살아 있 는 것 은 의미 가 없습니다.app 은 실행 을 중단 합 니 다.
안 드 로 이 드 이상 캡 처 체 제 를 정리 하고 익숙 한 학생 들 은 건 너 뛰 고 바로 다음 절 에 들 어 갈 수 있 습 니 다.
  • Thread.setCaughtExceptionPreHandler()는 모든 스 레 드 를 덮어 쓰 고 DefaultExceptionHandler 를 되 돌리 기 전에 호출 합 니 다
  • Thread.setCaughtExceptionHandler()역시 모든 스 레 드 를 덮어 씁 니 다.응용 층 에서 중복 호출 될 수 있 고 호출 될 때마다 지난번 에 설정 한 Default UncaughtExceptionHandler 를 덮어 씁 니 다
  • 현재 스 레 드 의 이상 만 덮어 쓸 수 있 습 니 다.사용자 정의 UncaughtExceptionHandler 가 있 는 스 레 드 에 서 는 전체 Default UncaughtHandler 를 무시 합 니 다.
    말 이 여기까지 나 왔 으 니 never crash 의 큰 수 를 받 아 보 세 요.
    crash 를 하지 않 으 려 면 스 레 드 가 exception 을 던 지지 않도록 할 수 밖 에 없습니다.만약 에 우리 가 한 스 레 드 의 모든 조작 을 try-catch 로 보호 할 수 있다 면 이론 적 으로 app never crash 를 할 수 있 습 니 다.안 드 로 이 드 는 Handler 이벤트 구동 체 제 를 기반 으로 app 이 시 작 될 때 메 인 스 레 드 에 있 는 Message Queue 에 데 드 순환 동작 을 제출 할 수 있 습 니 다.이 데 드 순환 에서 poll 사건 을 계속 제거 하고 이 데 드 순환 을 try-catch 로 하면 모든 메 인 스 레 드 의 이상 이 catch 에 걸 려 서 app 은 다 시 는 crash 가 발생 하지 않 습 니 다.
    
    private fun openCrashProtected() {
        Log.d(tag, "openCrashProtected")
        Handler(Looper.getMainLooper()).post {
          while (true) {
            try {
              Looper.loop()
              Log.d(tag, "main looper execute loop")
            } catch (e: Throwable) {
              //            catch ,      crash
              Log.e(tag, "catch exception: " + e.message)
            }
          }
        }
      }
    누군가가 말 할 것 같 습 니 다.당신 이 이렇게 catch 메 인 스 레 드 의 이상 을 잡 으 면 페이지 가 엉망 이 될 것 입 니 다.그럼 에 도 불구 하고 catch 에서 업무 보 호 를 할 수 있 잖 아 요.예 를 들 어 제 가 여기 서 취 하 는 방법 은 스 택 꼭대기 activity 를 닫 는 것 입 니 다.Activity LifeCycle 을 해결 하고 Activity 스 택 을 유지 합 니 다.
    
    private fun registerLifeCycle() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
          override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            ActivityStack.Instance().push(activity)
          }
    
          override fun onActivityResumed(activity: Activity) {
          }
    
          override fun onActivityStarted(activity: Activity) {
          }
    
          override fun onActivityPaused(activity: Activity) {
    
          }
    
          override fun onActivityDestroyed(activity: Activity) {
            ActivityStack.Instance().pop(activity)
          }
    
          override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
    
          }
    
          override fun onActivityStopped(activity: Activity) {
          }
        })
      }
    그리고 catch 가 이상 을 잡 았 을 때,
    
    //       ,    activity
    ActivityStack.Instance().curr()?.finish()
    github 코드
    마지막 으로 드 립 니 다.
    이상 은 안 드 로 이 드 앱 이 crash 를 할 수 있 는 원인 과 해결 방법 에 대한 상세 한 내용 입 니 다.안 드 로 이 드 앱 crash 에 관 한 자 료 는 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기