I have a List<CustomObject>
(where CustomObject
comes from an external library -- I can't make changes to it). I want to save this in onSaveInstanceState(Bundle)
, but I can't seem to do it. Here are the options that I've tried:
outState.putSerializable(KEY, (ArrayList<CustomObject>) myList); // because myList is instantiated as an ArrayList
outState.putSerializable(KEY, myList.toArray());
Both options work when switching orientation on the phone (yes, onSaveInstanceState
is called when switching orientation -- I checked in logcat). However, when the current activity tries to start another one (with startActivity(Intent)
), Android pauses the current activity and calls onSaveInstanceState()
again. This time, it fails, for some reason unknown to me. The fishy thing is that onSaveInstanceState()
executes successfully. The stack trace printed doesn't point to any of my code:
E/AndroidRuntime(23898): java.lang.RuntimeException: Parcel: unable to marshal value my.custom.Object@5e07e43b
E/AndroidRuntime(23898): at android.os.Parcel.writeValue(Parcel.java:1087)
E/AndroidRuntime(23898): at android.os.Parcel.writeArray(Parcel.java:519)
E/AndroidRuntime(23898): at android.os.Parcel.writeValue(Parcel.java:1072)
E/AndroidRuntime(23898): at android.os.Parcel.writeMapInternal(Parcel.java:469)
E/AndroidRuntime(23898): at android.os.Bundle.writeToParcel(Bundle.java:1445)
E/AndroidRuntime(23898): at android.os.Parcel.writeBundle(Parcel.java:483)
E/AndroidRuntime(23898): at android.app.ActivityManagerProxy.activityPaused(ActivityManagerNative.java:1427)
E/AndroidRuntime(23898): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3106)
E/AndroidRuntime(23898): at android.app.ActivityThread.access$2400(ActivityThread.java:119)
E/AndroidRuntime(23898): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870)
E/AndroidRuntime(23898): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(23898): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(23898): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(23898): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23898): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(23898): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(23898): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(23898): at dalvik.system.NativeStart.main(Native Method)
Is there any way to store custom objects in the instance state?
Make your CustomObject
implement Parcelable
and use:
outState.putParcelable(KEY, myList);
onSaveInstanceState(outState);
Also check this tutorial.
EDIT after CommonsWare comment:
If your CustomObject
doesn't implement Serializable
or Parcelable
I would try wrapping it inside an object of your own and add:
private void readObject(ObjectInputStream aStream) throws IOException, ClassNotFoundException { /*Your deserialization */ }
private void writeObject(ObjectOutputStream aStream) throws IOException { /*Your serialization */}
Have your List<CustomObject>
be held by a service and make it accessible to your activities via the local binding pattern.
Not only do you not have to worry about holding onto it in your instance state, but you have a bit better control over the lifetime of those objects in memory. Instance state lifetime is controlled by Android; how long a Service
holds onto the objects is controlled by you. Particularly if CustomObject
might be big, or the list might be long, I would rather you have greater control over how long that RAM is consumed.
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