In English | 中文
GBU is an Android library that tries to fix your app when it crashes. You will never get the hated "X has stopped" dialog.
You can download an apk of the demo project.
The Gradle Dependency is available via jCenter
Add dependencies directly
implementation 'god.bless.you:gbu:0.0.1'
Integrate with kotlin
class App : Application() {
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
Gbu
}
}
Gbu 'fix' the crash in the Activity lifecycle by hooking ActivityThread
's member mInstrumentation
GbuInstrumentationImpl.kt
override fun callActivityOnCreate(activity: Activity?, icicle: Bundle?) {
try {
super.callActivityOnCreate(activity, icicle)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnCreate(activity: Activity?, icicle: Bundle?, persistentState: PersistableBundle?) {
try {
super.callActivityOnCreate(activity, icicle, persistentState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnNewIntent(activity: Activity?, intent: Intent?) {
try {
super.callActivityOnNewIntent(activity, intent)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnRestart(activity: Activity?) {
try {
super.callActivityOnRestart(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnStart(activity: Activity?) {
try {
super.callActivityOnStart(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnResume(activity: Activity?) {
try {
super.callActivityOnResume(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnPause(activity: Activity?) {
try {
super.callActivityOnPause(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnStop(activity: Activity?) {
try {
super.callActivityOnStop(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnDestroy(activity: Activity?) {
try {
super.callActivityOnDestroy(activity)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnPostCreate(activity: Activity?, icicle: Bundle?) {
try {
super.callActivityOnPostCreate(activity, icicle)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnPostCreate(activity: Activity?, icicle: Bundle?, persistentState: PersistableBundle?) {
try {
super.callActivityOnPostCreate(activity, icicle, persistentState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnSaveInstanceState(activity: Activity?, outState: Bundle?) {
try {
super.callActivityOnSaveInstanceState(activity, outState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnSaveInstanceState(activity: Activity?, outState: Bundle?, outPersistentState: PersistableBundle?) {
try {
super.callActivityOnSaveInstanceState(activity, outState, outPersistentState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnRestoreInstanceState(activity: Activity?, savedInstanceState: Bundle?) {
try {
super.callActivityOnRestoreInstanceState(activity, savedInstanceState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
override fun callActivityOnRestoreInstanceState(activity: Activity?, savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
try {
super.callActivityOnRestoreInstanceState(activity, savedInstanceState, persistentState)
} catch (e: Throwable) {
e.printStackTrace()
}
}
Gbu 'fix' the crash in the Service&BroadcastReceiver lifecycle by hooking Instrumentation
's method onException
GbuInstrumentationImpl.kt
class GbuInstrumentationImpl(base: Instrumentation) : GbuInstrumentationWrapper(base) {
override fun onException(obj: Any?, e: Throwable?): Boolean {
GbuActivityThread.handleException(obj)
return true
}
}
GbuActivityThread.kt
object GbuActivityThread {
fun handleException(obj: Any?) {
if (Gbu.debug) {
GbuLog.d(codeToString(mMsg?.what!!))
}
if (obj is Service) {
when (mMsg?.what) {
CREATE_SERVICE -> handleCreateService(obj)
SERVICE_ARGS -> handleServiceArgs(obj)
STOP_SERVICE -> handleStopService(obj)
BIND_SERVICE -> handleBindService(obj)
UNBIND_SERVICE -> handleUnbindService(obj)
}
} else if (obj is BroadcastReceiver) {
GbuBroadcastReceiver.setPendingResult(obj, null)
}
}
}
object Gbu {
init {
Handler(Looper.getMainLooper()).post {
while (true) {
try {
Looper.loop()
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
Thread.setDefaultUncaughtExceptionHandler { _: Thread, throwable: Throwable ->
throwable.printStackTrace()
}
}
}
Pengfeng Wang(王鹏锋)
email: ximsfei@gmail.com