A Crash Handling library for Android projects that automatically stores all crash logs in a file until intentionally cleared. It also records the time of the last exception, making it easy to review and debug issues by sharing the logs.
1. Setup
1.1 Kotlin DSL
1.2 Groovy DSL
2. Usage
2.1 Default Crash Hanlder
2.2 Formatter and Logger
2.3 Restart after crash
2.4 Custom Crash handler
2.5 Loading Crash data in Activity
2.6 Thread specific crash handler
3. Custom Crash Handler UI
3.1 Custom Activity Implementation or See File
3.2 Custom Activity Implementation for Compose or See File
4. License
Step 1: Project level build.gradle.kts / settings.gradle.kts
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() maven("https://jitpack.io") } }
Step 2: Module level build.gradle
dependencies {
implementation("com.github.Bhuvaneshw:CrashHandler:$version")
}
Replace $version with latest version
Latest Version:
Example:
dependencies {
implementation("com.github.Bhuvaneshw:CrashHandler:1.0.0")
}
Step 1: Project level build.gradle / settings.gradle
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() maven { url 'https://jitpack.io' } } }
Step 2: Module level build.gradle
dependencies {
implementation 'com.github.Bhuvaneshw:CrashHandler:$version'
}
Extend Application with CrashHandlerApplication and call installCrashHandler()
Koltin
class MyApp : CrashHandlerApplication() {
init {
installCrashHandler()
}
}
Java
public class MyApp extends CrashHandlerApplication {
@Override
public void onCreate() {
super.onCreate();
initCrashHandler();
}
}
Register in AndroidManifiest
<application
android:name=".MyApp"
...>
...
</application>
Note
This default handler will not restart app after crash. See Restart after crash section
You can provide Custom Formatter by extending ErrorMessageFormatter and pass it in installCrashHandler
You can provide Custom Logger by extending CrashLogger and pass it in installCrashHandler Koltin
class MyApp : CrashHandlerApplication() {
init {
installCrashHandler(
errorMessageFormatter = DefaultErrorMessageFormatter, // OR timedErrorMessageFormatter()
logger = AndroidErrorLogger(),
)
}
}
Java
public class MyApp extends CrashHandlerApplication {
@Override
public void onCreate() {
super.onCreate();
initCrashHandler(DefaultErrorMessageFormatter.INSTANCE, new RestartAppCallback(this), new AndroidErrorLogger());
}
}
Note
The default formatter is DefaultErrorMessageFormatter and the default logger is AndroidErrorLogger
Note
TimedErrorMessageFormatter follows Decorator Patter, to create instance use timedErrorMessageFormatter() extension function for Kotlin and new TimedErrorMessageFormatter(this, DefaultErrorMessageFormatter.INSTANCE) for Java
Provide RestartAppCallback() while initializing the crash handler
Kotlin
class MyApp : CrashHandlerApplication() {
init {
installCrashHandler(callback = RestartAppCallback(this))
}
}
Java
public class MyApp extends CrashHandlerApplication {
@Override
public void onCreate() {
super.onCreate();
initCrashHandler(
DefaultErrorMessageFormatter.INSTANCE,
new RestartAppCallback(this),
new AndroidErrorLogger()
);
}
}
Override startCrashHandlerActivity() and provide your custom activity class
Kotlin
class CustomCrashHandlerApp : CrashHandlerApplication() {
init {
installCrashHandler()
}
override fun startCrashHandlerActivity(defaultActivityClass: Class<*>) {
super.startCrashHandlerActivity(CustomCrashHandlerActivity::class.java) // Provide your custom activity class
}
}
Java
public class DefaultCrashHandlerApp extends CrashHandlerApplication {
@Override
public void onCreate() {
super.onCreate();
initCrashHandler();
}
@Override
protected void startCrashHandlerActivity(@NonNull Class<?> defaultActivityClass) {
super.startCrashHandlerActivity(CustomCrashHandlerActivity.class); // Provide your custom activity class
}
}
Caution
Calling loadErrorLog() on main thread is not allowed, throws ReadLogOnMainThreadException.
Kotlin
val log: ErrorLog = crashHandler.loadErrorLog()
val errors: MutableList<String>? = log.errors
val simplifiedLog: String = log.simplifiedLog()
val lastErrorTime: String? = log.lastErrorTime
Tip
Using coroutine with IO dispatcher is recommended
Java
ErrorLog log = CrashHandlerUtilsKt.getCrashHandler(context).loadErrorLog();
//Works only when the context.applicationContext is an instance of CrashHandler,
//i.e The application must implement CrashHandler, like extending CrashHandlerApplication
List<String> errors = log.getErrors();
String simplifiedLog = log.simplifiedLog();
String lastErrorTime = log.getLastErrorTime();
You can provide specific threads instead of setting it for all threads.
Kotlin
class MyApp : CrashHandlerApplication() {
init {
installCrashHandler(threads = arrayOf(myThread1, myThread2, myThreadN))
//OR
// installCrashHandler(
// errorMessageFormatter = DefaultErrorMessageFormatter,
// callback = null,
// logger = AndroidErrorLogger(),
// myThread1, myThread2, myThreadN
//)
}
}
Java
public class MyApp extends CrashHandlerApplication {
@Override
public void onCreate() {
super.onCreate();
initCrashHandler(DefaultErrorMessageFormatter.INSTANCE, new RestartAppCallback(this), new AndroidErrorLogger(), myThread1, myThread2, myThreadN);
}
}
Note
For more details see the CrashHandlerActivity implementation.
Note
If you are using compose in your project see CustomCrashHandlerActivity for implementation.
CrashHandler - Crash Handling Library
Copyright (C) 2024 Bhuvaneshwaran
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.