GodBlessYou: 让你的应用不再崩溃

综合技术 2017-12-19 阅读原文

项目地址: github.com/ximsfei/God…

GBU尝试在运行时修复Android应用的崩溃问题,在使部分功能失效的前提下,让应用继续运行。使用GBU以后,应用将不再会出现”X 已停止运行”的对话框。

你可以下载demo apk来体验一下.

内容

    • 修复Activity中的Crash
    • 修复BroadcastReceiver中的Crash

实现原理

修复Activity中的Crash

Android framework 通过 Instrumentation
来调用Activity的所有生命周期方法,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()
    }
}

修复Service和BroadcastReceiver中的Crash

Android framework 在调用四大组件生命周期的时候,如果出现了异常,会回调 Instrumentation.onException
方法。GBU 通过 Instrumentation
的方法 onException
返回 true
来尝试修复 Service
BroadcastReceiver
生命周期回调中的崩溃。同时手动执行framework未完成的代码,防止生命周期不完整引起的anr。

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)
        }
    }
}

修复其他Crash

参照网上的一些资料实现其他崩溃的捕获,同时保证主线程不会因为崩溃而退出。

object Gbu {
    init {
        Handler(Looper.getMainLooper()).post {
            while (true) {
                try {
                    Looper.loop()
                } catch (e: Throwable) {
                    e.printStackTrace()
                }
            }
        }
        Thread.setDefaultUncaughtExceptionHandler { _: Thread, throwable: Throwable ->
            throwable.printStackTrace()
        }
    }
}
稀土掘金

责编内容by:稀土掘金阅读原文】。感谢您的支持!

您可能感兴趣的

安卓广播的底层实现原理 相信广播大家都有用过,也知道安卓广播的一些基础知识,如静态广播、动态广播、粘性广播等等,但相信很多人都不知道系统层面是怎样实现这些广播特性的,这篇文章就让我们来...
BroadcastReceiver广播的注册、发送和接收过程分析... 1. 简介 广播作为Android的四大组件之一,能够实现组件之间的通信。广播过程主要就是注册、发送和接收过程。广播使用了设计模式中的 观察者模式 ...
ANR 产生原因以及原因分析 ANR:Application Not Responding,即应用无响应 ANR.png 官方给出的产生ANR...
BroadcastReceiver基础知识 什么是广播 在Android中,广播是一种广泛运用的在应用程序之间传输信息的机制,Android中我们要发送的广播内容是一个Intent,这个Intent中...
本地广播LocalBroadcastManager基本使用与源码解析... BroadcastReceiverBroadcastReceiver是Android四大组件之一,我们都比较熟悉,称它为“广播” ...