In English | 中文
GBU 尝试在运行时修复Android应用的崩溃问题,在使部分功能失效的前提下,让应用继续运行。使用GBU以后,应用将不再会出现"X 已停止运行"的对话框。
你可以下载demo apk来体验一下.
在build.gradle
中直接添加依赖
implementation 'god.bless.you:gbu:0.0.2'
使用kotlin在Application中初始化
class App : Application() {
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
Gbu.init(this)
.setDebug(true)
.enableLifecycleCrash(true)
.enableOtherCrash(false)
.install()
}
}
GBU 通过反射ActivityThread
的成员变量mInstrumentation
来尝试修复Activity
生命周期回调中的崩溃。
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 通过Instrumentation
的方法onException
返回true
来尝试修复Service
和BroadcastReceiver
生命周期回调中的崩溃。
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()
}
}
}
姓名: 王鹏锋
email: ximsfei@gmail.com