无法保存 RelativeLayout 的状态
Can't save state of RelativeLayout
我正在制作一个具有 activity 的应用程序,用户可以在其中向对象添加图片,在这里我让用户选择是从图库中选择图片还是使用相机。这两个选项都会启动一个 Intent(在用户完成选择图片后)returns 到 activity 它来自。
但我遇到的问题是,当用户回来时,有时 activity 的一些数据会丢失,所以我 "reload" 它使用 savedInstance。我尝试保存的对象之一是扩展 RelativeLayout 的自定义视图的数组列表。但是当我加载以下数据时,出现以下错误:
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.access0(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.access0(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.access0(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)
这是我自定义的 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);
}
}
还有我的 onSaveInstanceState 和 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");
}
我做错了什么?
你的概念是错误的:你不应该保存整个小部件,而是重新创建它们的信息。
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.
来自:Android Activity Lifecycle, Android SDK Docs
因此将信息保存为整数(在您的示例中用于标识所选选项卡)或其他原语并设置在 onRestoreInstanceState
中。
我正在制作一个具有 activity 的应用程序,用户可以在其中向对象添加图片,在这里我让用户选择是从图库中选择图片还是使用相机。这两个选项都会启动一个 Intent(在用户完成选择图片后)returns 到 activity 它来自。
但我遇到的问题是,当用户回来时,有时 activity 的一些数据会丢失,所以我 "reload" 它使用 savedInstance。我尝试保存的对象之一是扩展 RelativeLayout 的自定义视图的数组列表。但是当我加载以下数据时,出现以下错误:
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.access0(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.access0(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.access0(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)
这是我自定义的 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);
}
}
还有我的 onSaveInstanceState 和 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");
}
我做错了什么?
你的概念是错误的:你不应该保存整个小部件,而是重新创建它们的信息。
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.
来自:Android Activity Lifecycle, Android SDK Docs
因此将信息保存为整数(在您的示例中用于标识所选选项卡)或其他原语并设置在 onRestoreInstanceState
中。