Android 全局监听崩溃

151 阅读1分钟

初始化

在Application onCreate进行初始化

// 只在主线程空闲时执行,false表示执行一次后就不再被调用
//必须传递applicationContext
Looper.getMainLooper().queue.addIdleHandler {
    // 初始化全局崩溃捕获器
    CaughtExceptionHandler.init(applicationContext)
    false
}

单例类

/**
 * 全局异常捕获器,可以在崩溃时处理逻辑
 * */
class CaughtExceptionHandler private constructor(private val context: Context) :
    Thread.UncaughtExceptionHandler {

    private val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()

    companion object {
        fun init(context: Context) {
            val handler = CaughtExceptionHandler(context)
            Thread.setDefaultUncaughtExceptionHandler(handler)
        }
    }

    override fun uncaughtException(thread: Thread, throwable: Throwable) {
        // 打印崩溃日志
        throwable.printStackTrace()

        // 在这里可以进行自定义处理,比如记录日志或显示弹窗
        showCrashDialog(throwable)

        // 如果有默认的处理器,继续交由默认处理器处理
        defaultHandler?.uncaughtException(thread, throwable)
    }

    private fun showCrashDialog(throwable: Throwable) {
        // 需要启动一个新的线程来显示弹窗
        Thread {
            Looper.prepare()
            val errorMessage = throwable.localizedMessage ?: "发生未知错误"
            Log.e("CrashHandler", "应用发生崩溃: $errorMessage")
            restartApplication()
            Looper.loop()
        }.start()
    }


    //重启app
    private fun restartApplication() {
        val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
        intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(intent)
        // 结束当前进程
        android.os.Process.killProcess(android.os.Process.myPid())
        exitProcess(0)
    }
}