Add Crash activity (#8216)
* Add Crash activity When the application crashes this sends them to a different activity with the cause message and an option to dump the crash logs * Review changes
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package eu.kanade.tachiyomi.crash
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import eu.kanade.presentation.crash.CrashScreen
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.util.view.setComposeContent
|
||||
|
||||
class CrashActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val exception = GlobalExceptionHandler.getThrowableFromIntent(intent)
|
||||
setComposeContent {
|
||||
CrashScreen(
|
||||
exception = exception,
|
||||
onRestartClick = {
|
||||
finishAffinity()
|
||||
startActivity(Intent(this@CrashActivity, MainActivity::class.java))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package eu.kanade.tachiyomi.crash
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.Json
|
||||
import logcat.LogPriority
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class GlobalExceptionHandler private constructor(
|
||||
private val applicationContext: Context,
|
||||
private val defaultHandler: Thread.UncaughtExceptionHandler,
|
||||
private val activityToBeLaunched: Class<*>,
|
||||
) : Thread.UncaughtExceptionHandler {
|
||||
|
||||
object ThrowableSerializer : KSerializer<Throwable> {
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor("Throwable", PrimitiveKind.STRING)
|
||||
|
||||
override fun deserialize(decoder: Decoder): Throwable =
|
||||
Throwable(message = decoder.decodeString())
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Throwable) =
|
||||
encoder.encodeString(value.stackTraceToString())
|
||||
}
|
||||
|
||||
override fun uncaughtException(thread: Thread, exception: Throwable) {
|
||||
try {
|
||||
logcat(priority = LogPriority.ERROR, throwable = exception)
|
||||
launchActivity(applicationContext, activityToBeLaunched, exception)
|
||||
exitProcess(0)
|
||||
} catch (_: Exception) {
|
||||
defaultHandler.uncaughtException(thread, exception)
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchActivity(
|
||||
applicationContext: Context,
|
||||
activity: Class<*>,
|
||||
exception: Throwable,
|
||||
) {
|
||||
val intent = Intent(applicationContext, activity).apply {
|
||||
putExtra(INTENT_EXTRA, Json.encodeToString(ThrowableSerializer, exception))
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
}
|
||||
applicationContext.startActivity(intent)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val INTENT_EXTRA = "Throwable"
|
||||
|
||||
fun initialize(
|
||||
applicationContext: Context,
|
||||
activityToBeLaunched: Class<*>,
|
||||
) {
|
||||
val handler = GlobalExceptionHandler(
|
||||
applicationContext,
|
||||
Thread.getDefaultUncaughtExceptionHandler() as Thread.UncaughtExceptionHandler,
|
||||
activityToBeLaunched,
|
||||
)
|
||||
Thread.setDefaultUncaughtExceptionHandler(handler)
|
||||
}
|
||||
|
||||
fun getThrowableFromIntent(intent: Intent): Throwable? {
|
||||
return try {
|
||||
Json.decodeFromString(ThrowableSerializer, intent.getStringExtra(INTENT_EXTRA)!!)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e) { "Wasn't able to retrive throwable from intent" }
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user