Exception handling is one of the most crucial part of any program and android is no different story.When any error or exception occurs, developers need to know
- Type of exception is it run-time or compile time or logical exception.
- Line of exception, piece of code where exception occurred.
- What to execute after catching exception.
In this article we will focus on what to do after catching such exception.
There are many tools available in market that focus on error reporting specially when application is in production build, Crashnalytics – fabric.io , ACRA , Google analytics, Play developer console, and newly introduces Google – firebase are among the popular error reporting tools. But they never provide any mechanism at app side to recover from that error.
But at codecrunch we have developed a mechanism to make app recover from exception and allow developer to show custom message / screen or to redirect at specific activity after exception.
Everyting we need is our exception class which is extends from an Exception class.In this example we have created ExceptionHandler.java implementing java.lang.Thread.UncaughtExceptionHandler i.e native exception handler in java.
public class ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler { private final Activity myContext; private final String LINE_SEPARATOR = "\n"; public ExceptionHandler(Activity context) { myContext = context; } public void uncaughtException(Thread thread, Throwable exception) { StringWriter stackTrace = new StringWriter(); exception.printStackTrace(new PrintWriter(stackTrace)); StringBuilder errorReport = new StringBuilder(); errorReport.append("************ CAUSE OF ERROR ************\n\n"); errorReport.append(stackTrace.toString()); errorReport.append("\n************ DEVICE INFORMATION ***********\n"); errorReport.append("Brand: "); errorReport.append(Build.BRAND); errorReport.append(LINE_SEPARATOR); errorReport.append("Device: "); errorReport.append(Build.DEVICE); errorReport.append(LINE_SEPARATOR); errorReport.append("Model: "); errorReport.append(Build.MODEL); errorReport.append(LINE_SEPARATOR); errorReport.append("Id: "); errorReport.append(Build.ID); errorReport.append(LINE_SEPARATOR); errorReport.append("Product: "); errorReport.append(Build.PRODUCT); errorReport.append(LINE_SEPARATOR); errorReport.append("\n************ FIRMWARE ************\n"); errorReport.append("SDK: "); errorReport.append(Build.VERSION.SDK); errorReport.append(LINE_SEPARATOR); errorReport.append("Release: "); errorReport.append(Build.VERSION.RELEASE); errorReport.append(LINE_SEPARATOR); errorReport.append("Incremental: "); errorReport.append(Build.VERSION.INCREMENTAL); errorReport.append(LINE_SEPARATOR); Toast.makeText(myContext,errorReport.toString(),Toast.LENGTH_LONG).show(); Intent intent = new Intent(myContext, ErrorRecoveryActvity.class); intent.putExtra("error", errorReport.toString()); myContext.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); } }
Here ErrorRecoveryActivity.class is custom activity allowing us to display error message or you can add your main activity as well.
Now we need to create an activity that extents AppCompatActivity, say we created BaseActivity.java, in it we need to run a thead allowing any uncaught exception to get redirected to our custom exception handler class.
public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); } }
Now this BaseActivity we have to extend in all activity of app instead of AppCompatActivity, this will allow us to catch any exception in app and redirect it to our custom made exception handler and from there we can show custom message or open any activity.
So from now onwards our MainActivity and all activities in app will look like.
public class MainActivity extends BaseActivity {
Happy Catching your bugs 🙂
Leave a Reply