package com.xxxx.xxx.utils
import android.app.Activity
import android.app.Application
import android.os.Bundle
import android.os.Looper
import android.os.Process
import android.widget.Toast
import kotlinx.coroutines.*
class CrashHandler private constructor() : Thread.UncaughtExceptionHandler,
Application.ActivityLifecycleCallbacks {
private lateinit var context: Application
private val activityList = arrayListOf<Activity>()
companion object {
val instance: CrashHandler by lazy(
mode = LazyThreadSafetyMode.SYNCHRONIZED
) { CrashHandler() }
}
fun init(context: Application): CrashHandler {
this.context = context
context.registerActivityLifecycleCallbacks(this)
Thread.setDefaultUncaughtExceptionHandler(this)
return this
}
override fun uncaughtException(thread: Thread, throwable: Throwable) {
try {
GlobalScope.launch(context = Dispatchers.Default) {
withContext(Dispatchers.Default) {
//TODO report the crash to Your 3rd Party or own Server.
//save what you need to savings
if (SharedPreferences.getCrashRestartCount < 2)
//TODO: saveInfo()
}
if (thread == Looper.getMainLooper().thread) {
//when a crash happened on the main thread show a short toast to the user
withContext(context = Dispatchers.Default) {
Looper.prepare()
Toast.makeText(
context, "crash occured,please try later",
Toast.LENGTH_SHORT
).show()
Looper.loop()
}
} else {
//when a crash happened on the child thread not block the UI thread, so can show a dialog to the user
withContext(context = Dispatchers.Main) {
//TODO: showAlertDialog()
}
}
}
if (thread == Looper.getMainLooper().thread) {
//let the main thread sleep 2s to show a short toast to the user
Thread.sleep(2000)
restartApp()
}
} catch (e: Exception) {
}
}
private fun restartApp() {
context.startActivity(
context.packageManager.getLaunchIntentForPackage(
context.packageName
)
)
Process.killProcess(Process.myPid())
}
override fun onActivityCreated(p0: Activity, p1: Bundle?) {
activityList.add(p0)
}
override fun onActivityStarted(p0: Activity) {
}
override fun onActivityResumed(p0: Activity) {
}
override fun onActivityPaused(p0: Activity) {
}
override fun onActivityStopped(p0: Activity) {
}
override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {
}
override fun onActivityDestroyed(p0: Activity) {
activityList.remove(p0)
}
}
-----------------------------End-----------------------------