GodBlessYou
專案地址: github.com/ximsfei/God…
GBU嘗試在執行時修復Android應用的崩潰問題,在使部分功能失效的前提下,讓應用繼續執行。使用GBU以後,應用將不再會出現”X 已停止執行”的對話方塊。
你可以下載demo apk來體驗一下.
內容
實現原理
修復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()
}
}
}
複製程式碼