GodBlessYou
GodBlessYou copied to clipboard
GBU is an Android library that tries to fix your app when it crashes. God bless your app no longer crashes.
GodBlessYou
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.
Table of Contents
- Gradle Dependency
- Integration
- How it works
- Fix Activity Crash
- Fix Service Crash
- Fix BroadcastReceiver Crash
- Fix Other Crash
- About Author
- LICENSE
Gradle Dependency
The Gradle Dependency is available via jCenter
Add dependencies directly
implementation 'god.bless.you:gbu:0.0.2'
Integration
Integrate with kotlin
class App : Application() {
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
Gbu.init(this)
.setDebug(true)
.enableLifecycleCrash(true)
.enableOtherCrash(false)
.install()
}
}
How it works
Fix Activity Crash
GBU 'fix' the crash in the Activity lifecycle by hooking ActivityThread's field 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()
}
}
Fix Service and BroadcastReceiver Crash
GBU 'fix' the crash in the Service and BroadcastReceiver lifecycle by hooking Instrumentation's method onException.
GbuInstrumentationImpl.kt
class GbuInstrumentationImpl(base: Instrumentation) : GbuInstrumentationWrapper(base) {
/**
* If true is returned, the system will proceed as if the exception didn't happen.
*/
override fun onException(obj: Any?, e: Throwable?): Boolean {
GbuActivityThread.handleException(obj)
return true
}
}
GbuActivityThread.kt
object GbuActivityThread {
/**
* Prevent incomplete lifecycle leads to anr.
*/
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)
}
}
}
Fix Other Crash
object Gbu {
init {
Handler(Looper.getMainLooper()).post {
// Do not let the main thread exit.
while (true) {
try {
Looper.loop()
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
// Catch all threads crashes
Thread.setDefaultUncaughtExceptionHandler { _: Thread, throwable: Throwable ->
throwable.printStackTrace()
}
}
}
About Author
Pengfeng Wang(王鹏锋)
email: [email protected]