Skip to content

Instantly share code, notes, and snippets.

@knezmilos13
Forked from fbcbl/crash_handling2.kt
Created September 18, 2017 07:53
Show Gist options
  • Save knezmilos13/62f7adbc23edd53a72f149877c60f3b7 to your computer and use it in GitHub Desktop.
Save knezmilos13/62f7adbc23edd53a72f149877c60f3b7 to your computer and use it in GitHub Desktop.
Crash Handling II
class AppExceptionHandler(val systemHandler: Thread.UncaughtExceptionHandler,
val crashlyticsHandler: Thread.UncaughtExceptionHandler,
application: Application) : Thread.UncaughtExceptionHandler {
private var lastStartedActivity: Activity? = null
private var startCount = 0
init {
application.registerActivityLifecycleCallbacks(
object : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity?) {
// empty
}
override fun onActivityResumed(activity: Activity?) {
// empty
}
override fun onActivityStarted(activity: Activity?) {
startCount++
lastStartedActivity = activity
}
override fun onActivityDestroyed(activity: Activity?) {
// empty
}
override fun onActivitySaveInstanceState(activity: Activity?,
outState: Bundle?) {
// empty
}
override fun onActivityStopped(activity: Activity?) {
startCount--
if (startCount <= 0) {
lastStartedActivity = null
}
}
override fun onActivityCreated(activity: Activity?,
savedInstanceState: Bundle?) {
// empty
}
})
}
override fun uncaughtException(t: Thread?, e: Throwable) {
Log.e(e)
lastStartedActivity?.let { activity ->
val isRestarted = activity.intent
.getBooleanExtra(RESTARTED, false)
val lastException = activity.intent
.getSerializableExtra(LAST_EXCEPTION) as Throwable?
if (!isRestarted || !isSameException(e, lastException)) {
killThisProcess {
// signal exception to be logged by crashlytics
crashlyticsHandler.uncaughtException(t, e)
val intent = activity.intent
.putExtra(RESTARTED, true)
.putExtra(LAST_EXCEPTION, e)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_CLEAR_TASK)
with(activity) {
finish()
startActivity(intent)
}
}
} else {
Log.d("The system exception handler will handle the caught exception.")
killThisProcess { systemHandler.uncaughtException(t, e) }
}
} ?: killThisProcess {
crashlyticsHandler.uncaughtException(t, e)
systemHandler.uncaughtException(t, e)
}
}
/**
* Not bullet-proof, but it works well.
*/
private fun isSameException(originalException: Throwable,
lastException: Throwable?): Boolean {
if (lastException == null) return false
return originalException.javaClass == lastException.javaClass &&
originalException.stackTrace[0] == originalException.stackTrace[0] &&
originalException.message == lastException.message
}
private fun killThisProcess(action: () -> Unit = {}) {
action()
Process.killProcess(Process.myPid())
System.exit(10)
}
companion object {
private const val RESTARTED = "appExceptionHandler_restarted"
private const val LAST_EXCEPTION = "appExceptionHandler_lastException"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment