The Setup
I have an activity that only overrides onCreate(), onResume(), and onSaveInstanceState(). In onSaveInstanceState(), I put in a serializable object:
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putSerializable("obj", myObj); // myObj is of class MyClass state.putLong("long", longVar);
}
MyClass was originally an inner class inside the activity class, but for debugging, I even moved it to a separate file:
public class MyClass implements Serializable {
private static final long serialVersionUID = 0x98ED2F00;
....
}
The Steps:
Start the program again from Launcher, this time I get the following:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.Reports}: java.lang.RuntimeException Parcelable encountered ClassNotFoundException reading a serializable object {name = com.example.MyClass}
Caused by: java.lang.ClassNotFoundException: com.examp.MyClass in loader dalvik.System.PathClassLoader[.]
Clues and Observations:
The most important clue is: if I don't save myObj in onSaveInstanceState(), then everything is fine. And, putting any primitive types into the Bundle is fine, but not my objects.
The exception is thrown outside of my code, it happened between onCreate() and onResume(). It happened inside Android.
The class name in the error message is correct: com.example.MyClass. Originally it was an inner class inside the activity, but to isolate the problem, I moved it to a separate file, to no avail.
I believe the implementation of Serializable is correct, because it can be serialized to/from a file in other parts of the program.
Does anybody have an idea of any possible cause of this? Much appreciated! (Sorry I can't put detailed code here, because everything is intertwined here and there. I can only isolate as much as possible.)
OK, I think I found a solution to this problem.
It turned out that if the savedInstanceState parameter passed into onCreate() is not null, then one MUST deserialize any objects contained in that Bundle. I don't know why, but this is how I got rid of the problem. Originally my code in onCreate() has the logic that under some conditions, I disregard the savedInstanceState. Now what I do is as long as it's not null, I'll just deserialize everything out, then, based on other conditions, I decide if I use them or not.
So far it runs fine. But I have no idea about:
Why do I have to deserialize them out, and if I don't, exception happens?
What was Android doing to deserialize my things I put in savedInstanceState? I mean, I understand that Android may have put some information for its own use, but why does it come and try to deserialize my things? If it knows it doesn't know how to use them?
I've been fighting this same issue and the way I ended up resolving it was to implement Parceable
instead of Serializable
in the class I was stashing in the Bundle.
I was able to reliably reproduce the crash by using the DevTools app on the emulator (doesn't seem to work on a real device) and changing the Development Settings > Immediately destroy activities
to be checked. Changing my custom class to Parceable
and changing to putParcelable
in my onSaveInstanceState
seemed to fix the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With