-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
486 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,243 @@ | ||
# AutoFix | ||
# GodBlessYou | ||
|
||
![gbu-0.0.1](https://img.shields.io/badge/gbu-0.0.1-green.svg) | ||
![build](https://img.shields.io/badge/build-passing-green.svg) | ||
![license-apache-2.0](https://img.shields.io/badge/apache--2.0-blue.svg) | ||
|
||
In English | [中文](README_CN.md) | ||
|
||
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](#gradle-dependency) | ||
* [Integration](#integration) | ||
* [How it works](#how-it-works) | ||
* [Fix Activity Crash](#fix-activity-crash) | ||
* [Fix Service Crash](#fix-service-and-broadcastreceiver-crash) | ||
* [Fix BroadcastReceiver Crash](#fix-service-and-broadcastreceiver-crash) | ||
* [Fix Other Crash](#fix-other-crash) | ||
* [About Author](#about-author) | ||
* [LICENSE](#license-apache-2.0) | ||
|
||
## Gradle Dependency | ||
|
||
The Gradle Dependency is available via [jCenter](https://bintray.com/pengfeng/ximsfei/gbu) | ||
|
||
Add dependencies directly | ||
|
||
``` | ||
implementation 'god.bless.you:gbu:0.0.1' | ||
``` | ||
|
||
## Integration | ||
|
||
Integrate with kotlin | ||
|
||
``` | ||
class App : Application() { | ||
override fun attachBaseContext(base: Context?) { | ||
super.attachBaseContext(base) | ||
Gbu | ||
} | ||
} | ||
``` | ||
|
||
## How it works | ||
|
||
### Fix Activity Crash | ||
|
||
Gbu 'fix' the crash in the Activity lifecycle by hooking `ActivityThread`'s member `mInstrumentation` | ||
|
||
> GbuInstrumentationImpl.kt | ||
```kotlin | ||
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&BroadcastReceiver lifecycle by hooking `Instrumentation`'s method `onException` | ||
|
||
> GbuInstrumentationImpl.kt | ||
```kotlin | ||
class GbuInstrumentationImpl(base: Instrumentation) : GbuInstrumentationWrapper(base) { | ||
|
||
override fun onException(obj: Any?, e: Throwable?): Boolean { | ||
GbuActivityThread.handleException(obj) | ||
return true | ||
} | ||
} | ||
``` | ||
|
||
> GbuActivityThread.kt | ||
```kotlin | ||
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) | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Fix Other Crash | ||
|
||
```kotlin | ||
object Gbu { | ||
init { | ||
Handler(Looper.getMainLooper()).post { | ||
while (true) { | ||
try { | ||
Looper.loop() | ||
} catch (e: Throwable) { | ||
e.printStackTrace() | ||
} | ||
} | ||
} | ||
Thread.setDefaultUncaughtExceptionHandler { _: Thread, throwable: Throwable -> | ||
throwable.printStackTrace() | ||
} | ||
} | ||
} | ||
``` | ||
## About Author | ||
|
||
Pengfeng Wang(王鹏锋) | ||
|
||
email: ximsfei@gmail.com | ||
|
||
## [LICENSE Apache 2.0](LICENSE) |
Oops, something went wrong.