A summary of one sentence:Global exception handling is like installing a "safety network" to an App - keeping all uncaught crashes, recording logs, reporting the server, and then exiting gracefully to avoid users from seeing the ugly "stopped"!
1. Core implementation (three steps to get the safety net)
1. Custom crash handler (inherited from UncaughtExceptionHandler)
class GlobalCrashHandler : { // The native default processor (to be handed over to it in the end) private val defaultHandler = () override fun uncaughtException(thread: Thread, throwable: Throwable) { // 1. Record the crash log logCrash(throwable) // 2. Upload to the server uploadCrash(throwable) // 3. Elegant Exit (optional restart) exitAppGracefully() // 4. Call the default processor (triggering crash pop-up) defaultHandler?.uncaughtException(thread, throwable) } private fun logCrash(e: Throwable) { ("Crash", "Global crash: ", e) } private fun uploadCrash(e: Throwable) { // Use Retrofit or OkHttp to report to the server } private fun exitAppGracefully() { // Close all activities (()) (1) } }
2. Register the global processor in Application
class MyApp : Application() { override fun onCreate() { () // Set global exception capture (GlobalCrashHandler()) } }
3. Specify the Application class in AndroidManifest
<application android:name=".MyApp" ...> </application>
2. Precautions (Guidelines for avoiding pits)
Don't eat abnormalities:The default processor must be calleduncaughtException()
, otherwise the system service may be abnormal!
Special handling of main thread crash:
After the main thread crashes, the process will be killed by default. If you want to restart the Activity, you need to use it.Handler
Delayed execution:
Handler(()).post { // Restart MainActivity}
Processing of third-party SDKs:
Some SDKs (such as Firebase Crashlytics) override the default processor and need to set up a custom processor after initializing the SDK.
3. Advanced skills (enhanced version of safety net)
Record device information:In case of crash, the device model, system version, etc. will be included.
private fun collectDeviceInfo(): Map<String, String> { return mapOf( "Model" to , "Android Version" to ) }
Save the crash log locally:Avoid log loss caused by network problems.
private fun saveCrashToFile(e: Throwable) { val log = "Crash: ${()}" File(cacheDir, "").writeText(log) }
User-friendly tips:Capture the crash and pops up to the error page or jumps to the error page.
private fun showUserFriendlyMessage() { (this, "The program encounters problems and will be restarted soon", Toast.LENGTH_SHORT).show() }
4. Recommended third-party library (work-saving tools)
Firebase Crashlytics:Automatically capture crashes and provide detailed analysis panel.
// implementation ':firebase-crashlytics-ktx:18.6.0'
().setCrashlyticsCollectionEnabled(true)
Bugsnag:Support cross-platform crash monitoring and provide real-time alarms.
ACRA:Open source crash reporting library, custom reporting server.
This is the article about how Android handles global exceptions in this article. For more relevant content on Android global exceptions, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!