SoFunction
Updated on 2025-04-08

The reason why Android app crashes and solutions

There is a sentence inside the commonInit() method of the Android main entrance,

(new KillApplicationHandler(loggingHandler));

Without this sentence, the app would not crash. If you don't believe it, look inside.

public KillApplicationHandler(LoggingHandler loggingHandler) {
 @Override
 public void uncaughtException(Thread t, Throwable e) {
 //Catched exception   try {
     ......
     //Print crash log, display crash popup window, etc.     // Bring up crash dialog, wait for it to be dismissed
     ().handleApplicationCrash(
       mApplicationObject, new (e));
      } catch (Throwable t2) {
        .... 
      } finally {
        // Try everything to make sure this process goes away.
        (());//Kill the process        (10);
      }
    }
  } 

When the exception KillApplicationHandler catches the exception and completes a series of processing (mainly printing the crash log, notifying the AMS to display crash popups, etc.), the process will eventually be killed, so your app will crash.

Since it's all crashed, is it really feasible to customize the exception catcher to block crash?

Some people will definitely say that customize an exception catcher to overwrite the system's KillApplicationHandler, and then after catching the exception, if the process is not killed, the app will not crash, just like the following,

class MainApplication : Application() {
  override fun onCreate() {
    ()
     { _, e ->
      //Catch exceptions, only print logs, not kill processes      ("MainApplication", "${().name} Catched exception:${}")
    }
  }
}

This is actually just Lao Wang’s idea next door. Although he does protect the crash of the child thread, the app still cannot run normally when the main thread has an exception. This is because when the UncaughtExceptionHandler catches that the thread throws an exception, the thread cannot continue to survive after executing the processing in uncaughtException(). If the thread that throws the exception is the main thread, it means that the main thread will die. Even if you don’t kill the process, the process will be alive without any meaning, and the app will still stop running.

Let’s sort out the Android exception capture mechanism. Familiar students can skip it and go directly to the next section.

  • () overwrites all threads and will be called before the callback of DefaultExceptionHandler;
  • () Also back to cover all threads, it can be called repeatedly at the application layer, and after each call, it will overwrite the last set DefaultUncaughtExceptionHandler;
  • (), can only overwrite the exceptions of the current thread. If a thread has a custom UncaughtExceptionHandler, the global DefaultUncaughtHandler will be ignored during callback.

Since you have said this, please take the Never crash trick.

If you want to crash, you can only let the thread not throw exceptions, there is nothing else to do. If we can use try-catch to protect all operations of a thread, in theory, we can achieve app never crash. Since Android is based on the Handler event-driven mechanism, it can submit a dead loop operation to the MessageQueue in the main thread when the app is started, and poll events are continuously polled in this dead loop, and try-catch this dead loop, so that all exceptions in the main thread will be caught, so that the app will never crash again.

private fun openCrashProtected() {
    (tag, "openCrashProtected")
    Handler(()).post {
      while (true) {
        try {
          ()
          (tag, "main looper execute loop")
        } catch (e: Throwable) {
          //All exceptions in the main thread will be caught, so that no crash occurs          (tag, "catch exception: " + )
        }
      }
    }
  }

Someone may say that if you catch the main thread in this way, the page may be messy. That being said, you can do business protection in catch. For example, the approach I have taken here is to close the activity on the top of the stack. Solve ActivityLifeCycle, maintain an Activity stack,

private fun registerLifeCycle() {
    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
      override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        ().push(activity)
      }

      override fun onActivityResumed(activity: Activity) {
      }

      override fun onActivityStarted(activity: Activity) {
      }

      override fun onActivityPaused(activity: Activity) {

      }

      override fun onActivityDestroyed(activity: Activity) {
        ().pop(activity)
      }

      override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {

      }

      override fun onActivityStopped(activity: Activity) {
      }
    })
  }

Then when the catch exception is caught,

//The main thread has an exception, close the activity on the top of the stack().curr()?.finish()

github code

Finally presentedgithub repository code, please accept it with a smile.

The above is the detailed content of the reasons and solutions for Android app crash. For more information about Android app crash, please follow my other related articles!