7

I have an exception handler which handles exception from an Activity class, the exception handler looks like this.

public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    public static final String TAG = "Exception handler";
    private final Context activity;

    public ExceptionHandler(Context activity) {
        this.activity = activity;
    }

    @Override
    public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
        Intent error = new Intent(activity, ErrorCatcher.class);
        activity.startActivity(error);
    }
}

it is initialized from the activity class

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.e(TAG, "onRestart: Hey just created");
        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));
// other methods and function
}

when the control comes to the exception handler, the activity is not created, instead of a blank page that hangs my app.

The only message I get is

I/Timeline: Timeline: Activity_launch_request time:417281208 intent:Intent { cmp=com.yyy.xxx/com.yyy.xxx.Activities.Error }

EDIT: Ok, after some digging I find, if no exception is thrown then the activity is started (i.e I can see the Activity page) but when an exception is thrown that's when a blank page is displayed. Why is this the condition for only when an exception is thrown and what is a better way to handle exception in android?? any help?


EDIT 2 : it's similar to this https://codecrunch.co/blog/custom-error-handling-in-android/

2
  • I'd rename your target activity since Error might be confused with java.lang.Error especially when you're dealing with java.lang.Throwable in the same context.
    – Pawel
    Commented Aug 10, 2020 at 21:44
  • but that could not be the cause for it not working right??
    – Akash Jain
    Commented Aug 11, 2020 at 13:12

5 Answers 5

3
+50

before the startActivity, add error.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);. There are also more complete answers here

7
  • these are some wonderful answers , thank you, once these answer solve my issue i will accept your answer.
    – Akash Jain
    Commented Aug 17, 2020 at 17:40
  • never mind , it's not working at all showing the same state as before...
    – Akash Jain
    Commented Aug 17, 2020 at 18:30
  • Try to set your exception handler inside the Application constructor, not the Activity onCreate. Add a class that extends Application to your base folder, inside its constructor set the thread uncaughtexceptionhandler. You can pass "this" instead of "this.getApplicationContext()" and see if it loads your activity. Commented Aug 17, 2020 at 18:49
  • 1
    I created a project on github, try to compile it with and without the 'throw exception' and see the difference. Commented Aug 17, 2020 at 21:09
  • 1
    Remember to add the application class in the android manifest <application android:name=""> for it to work, sometimes I forget to do this. Commented Aug 18, 2020 at 21:50
3

This code may be helpful for you

Application application = (Application) context.getApplicationContext();
Intent intent = new Intent(application, ErrorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
application.startActivity(intent);

If not then notify me, I will send you complete code for exception handling!

2
  • hey , seems to work but one issue , as the link given by leaonardo , i face the same issue as the OP in the link , i keep getting the crash message before the activity starts...can you help me resolve that?
    – Akash Jain
    Commented Aug 17, 2020 at 17:42
  • never mind , it's not working at all showing the same state as before...
    – Akash Jain
    Commented Aug 17, 2020 at 18:29
1

It worked for when i used try/catch instead of

Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));

to handle exception's , it might not be the best approch but it's worth a try.

1

First off, you are using an Application Context to try and start an activity. This may be causing some of your problems. This can be done, but I think there is a simpler way for all this to play out.

It should also be noted that you forgot the rest of the code inside the

  @Override
public void uncaughtException
    ....
    android.os.Process.killProcess(android.os.Process.myPid());
    System.exit(10);

Why is this the condition for only when an exception is thrown...

It's because you have overridden the uncaughtException method. So when you get an uncaught exception, you are going to start the Error.class Activity.

  @Override
    public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
        Intent error = new Intent(activity, ErrorCatcher.class);
        activity.startActivity(error);
    }

...and what is a better way to handle exception in android??

There are a number of ways that you can handle an exception. It really depends on what the use case is. In general, you should be handling errors as they occur, at least in the beginning. You can either do this with a try/catch block on methods that can throw errors; or, you can "bubble up the error" to handle it in an appropriate place, depending on your app's architecture, by creating methods that throw errors. Without more detail, I'm not able to provide an accurate response as to the best way to handle errors. In my app's, I'll typically throw a toast, if it requires user notification, or another path if there is something like a network failure.

Exception handling is a complex issue and should be handled as such. There is no single right answer for how to handle errors. However, some basics are:

  1. Handle all exceptions. If you have a method that throws an error, make sure you wrap in a try/catch and handle appropriately. This should prevent any "uncaught exceptions".

  2. Be specific in the errors you are handling. It appears like you are trying to create a "catch-all" for any uncaught errors in your activity. I would not go about it that way. I would wrap all the code in a try/catch and handle the errors as they come up. As I think about your code, I'm guessing that the reason you get a blank screen is that you haven't created a layout for your error class, but I could be wrong.

TLDR; If I were you I'd get rid of the:

@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
    Intent error = new Intent(activity, ErrorCatcher.class);
    activity.startActivity(error);
}

Also get rid of this:

protected void onCreate(Bundle savedInstanceState) {
    Log.e(TAG, "onRestart: Hey just created");
    //Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this.getApplicationContext()));

From there I would figure out what methods are throwing errors and handle them when you call them. That is going to be the simplest method. From there you can consider a larger and more complex approach to error handling. You don't necessarily need to create a new activity for an error. If you want to, I'd do it in the finally block. Make sure you have created a layout for the error activity; otherwise, it will just be blank; added the error activity to the manifest (or it will crash).

try{
   //your add all your method calls here.
} catch (Exception E){
   //handle generic exception
} catch (ThreadException e){
   //handle the thread exception
   ...add more catches for more specific errors
} finally{
   //Optional call once all exceptions have been caught
   Intent error = new Intent(this, ErrorCatcher.class);
   startActivity(error);
}
7
  • there is a reason for catch all uncaught exception so i can catch them later, also if an exception occurs there is really not much that can be done to handle except to restart the app ( at least based on the app) though i could be wrong, also the layout exists and also populated with designs. finally i have my reasons to not get rid of the uncaughtException , but if you could tell me why this happens it would be great help.
    – Akash Jain
    Commented Aug 21, 2020 at 14:33
  • I told you why it happens in the first paragraph of my answer. Commented Aug 21, 2020 at 15:54
  • At the end of the day, I have never seen someone handle errors the way you are and I've been developing enterprise level code for almost a decade. Commented Aug 21, 2020 at 15:55
  • I updated my answer, as it appears you left some code out that might be helpful. Best of luck. Commented Aug 21, 2020 at 16:01
  • 1
    I think the main reason this question was asked was to catch all the exceptions so that your app doesn't crash without feedback, and not to improve bug correction. It is impossible to predict what may happen with your app in a load of different devices, and it gets worse as it increses in complexity. The best approach to bug correction, in my opinion, is to use log services like Crashlytics, and when you need to try/catch some exception, you do so where the exception happens, and use this custom exceptionhandler as a safenet for better user experience. Personally, I just let it crash. Commented Aug 22, 2020 at 18:17
-1

on your overrided uncaughtException method you better start the activity using this code

   startActivity(activity,Error.class);
1
  • 1
    startActivity cannot be called by a non-activity class directly, i.e class that does not extends the Activity class. and this will not help if i'am using a context.startActivity or just startActivity as both will still call the same function
    – Akash Jain
    Commented Aug 10, 2020 at 21:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.