0

I am making an application which has an activity where the user can add a picture to an object, here I give the user the choice between selecting a picture from the gallery or making a new one using the camera. Both of these options start an Intent which (after the user is done choosing a picture) returns to activity it came from.

But the problem I'm having is that when the user comes back sometimes some of the data of that activity is lost, so I "reload" it using a savedInstance. One of the objects I try to save is an arraylist of custom views that extend RelativeLayout. But when I load the data the following I get the following error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sition.projectmanager/com.example.sition.projectmanager.activities.ObjectActivity}: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.sition.projectmanager.TabButton)
           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
           at android.app.ActivityThread.access$700(ActivityThread.java:158)
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loop(Looper.java:176)
           at android.app.ActivityThread.main(ActivityThread.java:5365)
           at java.lang.reflect.Method.invokeNative(Native Method)
           at java.lang.reflect.Method.invoke(Method.java:511)
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
           at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.sition.projectmanager.TabButton)
           at android.os.Parcel.readSerializable(Parcel.java:2144)
           at android.os.Parcel.readValue(Parcel.java:2016)
           at android.os.Parcel.readListInternal(Parcel.java:2235)
           at android.os.Parcel.readArrayList(Parcel.java:1655)
           at android.os.Parcel.readValue(Parcel.java:1986)
           at android.os.Parcel.readMapInternal(Parcel.java:2226)
           at android.os.Bundle.unparcel(Bundle.java:223)
           at android.os.Bundle.getParcelable(Bundle.java:1173)
           at android.app.Activity.onCreate(Activity.java:930)
           at com.example.sition.projectmanager.activities.ObjectActivity.onCreate(ObjectActivity.java:102)
           at android.app.Activity.performCreate(Activity.java:5326)
           at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225)
           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 
           at android.app.ActivityThread.access$700(ActivityThread.java:158) 
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 
           at android.os.Handler.dispatchMessage(Handler.java:99) 
           at android.os.Looper.loop(Looper.java:176) 
           at android.app.ActivityThread.main(ActivityThread.java:5365) 
           at java.lang.reflect.Method.invokeNative(Native Method) 
           at java.lang.reflect.Method.invoke(Method.java:511) 
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
           at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.io.InvalidClassException: android.widget.RelativeLayout; IllegalAccessException
           at java.io.ObjectStreamClass.resolveConstructorClass(ObjectStreamClass.java:692)
           at java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:653)
           at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1826)
           at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2013)
           at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1970)
           at android.os.Parcel.readSerializable(Parcel.java:2142)
           at android.os.Parcel.readValue(Parcel.java:2016) 
           at android.os.Parcel.readListInternal(Parcel.java:2235) 
           at android.os.Parcel.readArrayList(Parcel.java:1655) 
           at android.os.Parcel.readValue(Parcel.java:1986) 
           at android.os.Parcel.readMapInternal(Parcel.java:2226) 
           at android.os.Bundle.unparcel(Bundle.java:223) 
           at android.os.Bundle.getParcelable(Bundle.java:1173) 
           at android.app.Activity.onCreate(Activity.java:930) 
           at com.example.sition.projectmanager.activities.ObjectActivity.onCreate(ObjectActivity.java:102) 
           at android.app.Activity.performCreate(Activity.java:5326) 
           at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097) 
           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225) 
           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316) 
           at android.app.ActivityThread.access$700(ActivityThread.java:158) 
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296) 
           at android.os.Handler.dispatchMessage(Handler.java:99) 
           at android.os.Looper.loop(Looper.java:176) 
           at android.app.ActivityThread.main(ActivityThread.java:5365) 
           at java.lang.reflect.Method.invokeNative(Native Method) 
           at java.lang.reflect.Method.invoke(Method.java:511) 
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
           at dalvik.system.NativeStart.main(Native Method) 

Here is my custom RelativeLayout Class:

public class TabButton extends RelativeLayout implements Serializable {
    public TabButton(Context context) {
         super(context);
    }

    public TabButton(Context context, AttributeSet attrs) {
         super(context, attrs);
    }

    public TabButton(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
    }
}

And my onSaveInstanceState and onRestoreInstanceState:

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putSerializable("CURRENT_OBJECT",currentObject);
    outState.putSerializable("TAB_BUTTONS", tabButtons);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    currentObject = (Objectable) savedInstanceState.getSerializable("CURRENT_OBJECT");
    tabButtons = (ArrayList<TabButton>) savedInstanceState.getSerializable("TAB_BUTTONS");
}

What am I doing wrong?

Dennis van Opstal
  • 1,294
  • 1
  • 22
  • 44

1 Answers1

1

Your concept is wrong: You should not save entire widgets, but the information to recreate them.

However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.

from: Android Activity Lifecycle, Android SDK Docs

So save information as ints (in your example for identifying the selected tab) or other primitives and set in onRestoreInstanceState.

michi.0x5d
  • 959
  • 9
  • 13