Android activity 能够承受屏幕旋转但不能最小化
Android activity able to survive screen rotation but not minimizing
好的,所以我的应用程序可以正常工作,这样当屏幕方向改变时,它会将所有重要的变量信息存储在 savedInstanceState
包中,然后它会在创建时读回activity 再次没有问题。这有点棘手,因为我使用的是自定义对象的 ArrayList,所以我在我的自定义 class 中实现了 Serializable。这有助于它适用于屏幕旋转,但是当我单击主页按钮或以任何方式最小化应用程序时,它会崩溃。
这是抛出的错误:
01-23 10:50:54.961 19756-19756/com.example.spencers.arcgisgeodb E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.spencers.arcgisgeodb.agGDBFeatureTable)
at android.os.Parcel.writeSerializable(Parcel.java:1285)
at android.os.Parcel.writeValue(Parcel.java:1233)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1646)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2318)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3100)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.io.NotSerializableException: com.esri.core.geodatabase.GeodatabaseFeatureTable
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at android.os.Parcel.writeSerializable(Parcel.java:1280)
at android.os.Parcel.writeValue(Parcel.java:1233)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1646)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2318)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3100)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
根本问题似乎是这一行:
Caused by: java.io.NotSerializableException:com.esri.core.geodatabase.GeodatabaseFeatureTable
class 是我正在使用的外部库,不可编辑。
存储在 savedInstanceState 包中的我的自定义 class 的一部分:
public class agGDBFeatureTable implements Serializable {
private static final long serialVersionUID = 1L;
private GeodatabaseFeatureTable geodatabaseFeatureTable = null;
private boolean active = true;
private agLegendSymbol legendSymbols;
这是我的 onSaaveInstanceState 方法代码:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i("Saved Instance", "onSaveInstanceState");
for (int i = 0; i<gdbList.size(); i++) {
savedInstanceState.putSerializable(i + "", gdbList.get(i));
}
savedInstanceState.putInt("NUMBEROFLAYERS",gdbList.size());
}
现在,我的问题是,为什么我的自定义对象可以序列化、存储在包中并在屏幕旋转时重新启动,但是当应用程序最小化并通过同样的过程,它崩溃并抛出该错误?我该如何解决?
实现 Serializable 的 class 的所有字段也必须是可序列化的。显然(例外情况),GeodatabaseFeatureTable 不是。如果一个字段不可序列化,它必须被标记为瞬态的,像这样:
private transient GeodatabaseFeatureTable geodatabaseFeatureTable = null;
这样你就不会得到异常。现在你可以确定这个对象在反序列化后不会被持久化并再次为 null,或者你可以执行以下操作之一:
- 扩展 GeodatabaseFeatureTable class 并在那里实现 Serializable,然后使用扩展的 class - 注意:当然,如果 class 是最终的,这不是一个选项
- 通过覆盖 writeObject 和 readObject 方法并从 GeodatabaseFeatureTable 对象内部访问相关信息,在您的 agGDBFeatureTable class 中处理该对象的序列化 - 注意:很可能并非您需要的所有内容可从外部访问
希望对您有所帮助。祝你好运!
好的,所以我的应用程序可以正常工作,这样当屏幕方向改变时,它会将所有重要的变量信息存储在 savedInstanceState
包中,然后它会在创建时读回activity 再次没有问题。这有点棘手,因为我使用的是自定义对象的 ArrayList,所以我在我的自定义 class 中实现了 Serializable。这有助于它适用于屏幕旋转,但是当我单击主页按钮或以任何方式最小化应用程序时,它会崩溃。
这是抛出的错误:
01-23 10:50:54.961 19756-19756/com.example.spencers.arcgisgeodb E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.spencers.arcgisgeodb.agGDBFeatureTable)
at android.os.Parcel.writeSerializable(Parcel.java:1285)
at android.os.Parcel.writeValue(Parcel.java:1233)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1646)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2318)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3100)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.io.NotSerializableException: com.esri.core.geodatabase.GeodatabaseFeatureTable
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
at android.os.Parcel.writeSerializable(Parcel.java:1280)
at android.os.Parcel.writeValue(Parcel.java:1233)
at android.os.Parcel.writeMapInternal(Parcel.java:591)
at android.os.Bundle.writeToParcel(Bundle.java:1646)
at android.os.Parcel.writeBundle(Parcel.java:605)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2318)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3100)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
根本问题似乎是这一行:
Caused by: java.io.NotSerializableException:com.esri.core.geodatabase.GeodatabaseFeatureTable
class 是我正在使用的外部库,不可编辑。
存储在 savedInstanceState 包中的我的自定义 class 的一部分:
public class agGDBFeatureTable implements Serializable {
private static final long serialVersionUID = 1L;
private GeodatabaseFeatureTable geodatabaseFeatureTable = null;
private boolean active = true;
private agLegendSymbol legendSymbols;
这是我的 onSaaveInstanceState 方法代码:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Log.i("Saved Instance", "onSaveInstanceState");
for (int i = 0; i<gdbList.size(); i++) {
savedInstanceState.putSerializable(i + "", gdbList.get(i));
}
savedInstanceState.putInt("NUMBEROFLAYERS",gdbList.size());
}
现在,我的问题是,为什么我的自定义对象可以序列化、存储在包中并在屏幕旋转时重新启动,但是当应用程序最小化并通过同样的过程,它崩溃并抛出该错误?我该如何解决?
实现 Serializable 的 class 的所有字段也必须是可序列化的。显然(例外情况),GeodatabaseFeatureTable 不是。如果一个字段不可序列化,它必须被标记为瞬态的,像这样:
private transient GeodatabaseFeatureTable geodatabaseFeatureTable = null;
这样你就不会得到异常。现在你可以确定这个对象在反序列化后不会被持久化并再次为 null,或者你可以执行以下操作之一:
- 扩展 GeodatabaseFeatureTable class 并在那里实现 Serializable,然后使用扩展的 class - 注意:当然,如果 class 是最终的,这不是一个选项
- 通过覆盖 writeObject 和 readObject 方法并从 GeodatabaseFeatureTable 对象内部访问相关信息,在您的 agGDBFeatureTable class 中处理该对象的序列化 - 注意:很可能并非您需要的所有内容可从外部访问
希望对您有所帮助。祝你好运!