Home » Android » android – Pass an Exception as a Parcel

android – Pass an Exception as a Parcel

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am trying to pass an exception to an activity meant to dump the relevant information to the screen.

Currently I pass it through a bundle:

try {
    this.listPackageActivities();
} catch (Exception e) {
    Intent intent = new Intent().setClass(this, ExceptionActivity.class).putExtra("Exception", e);
    startActivity(intent);
}

But when it gets there:

if (!(this.bundle.getParcelable("Exception") != null))
    throw new IndexOutOfBoundsException("Index \"Exception\" does not exist in  the parcel." + "/n"
    + "Keys: " + this.bundle.keySet().toString());

This sweet exception is thrown but when I look at the keySet and the bundle details it tells me that there is one parcelable object with a key named “Exception”.

I understand that this has something to do with types but I do not understand what I am doing wrong. I just want to dump information about an exception, any exception to the screen. Is there a way to do that without having to condense all the information into a string every time?

How to&Answers:

I stumbled on this question when I was searching for a method to pass exceptions from a service to an activity. However, I found a better method, you can use the putSerializable() method of the Bundle class.

To add:

Throwable exception = new RuntimeException("Exception");
Bundle extras = new Bundle();
extras.putSerializable("exception", (Serializable) exception);

Intent intent = new Intent();
intent.putExtras(extras);

To retrieve:

Bundle extras = intent.getExtras();
Throwable exception = (Throwable) extras.getSerializable("exception");
String message = exception.getMessage();

Answer:

The class Exception doesn’t implement the Parcelable interface. Unless android is breaking some fundamental Java constructs of which I’m unaware, this means you can’t put an Exception as a Parcel into a Bundle.

If you want to “pass” the execption to a new Activity, just bundle up the aspects of it that you’re going to need in your new Activity. For example, let’s say you just want to pass along the exception message and the stacktrace. You’d so something like this:

Intent intent = new Intent().setClass(this,ExceptionActivity.class)
intent.putExtra("exception message", e.getMessage());
intent.putExtra("exception stacktrace", getStackTraceArray(e));
startActivity(intent);

where getStackTraceArray looks like this:

private static String[] getStackTraceArray(Exception e){
  StackTraceElement[] stackTraceElements = e.getStackTrace();
  String[] stackTracelines = new String[stackTraceElements.length];
  int i =0;
  for(StackTraceElement se : stackTraceElements){
    stackTraceLines[i++] = se.toString();
  }
  return stackTraceLines;
}