代码之家  ›  专栏  ›  技术社区  ›  Felix

以实例状态保存自定义对象数组

  •  13
  • Felix  · 技术社区  · 16 年前

    List<CustomObject> (其中 CustomObject 来自外部库--我无法对其进行更改)。我想把这个存起来 onSaveInstanceState(Bundle)

    outState.putSerializable(KEY, (ArrayList<CustomObject>) myList); // because myList is instantiated as an ArrayList
    outState.putSerializable(KEY, myList.toArray());
    

    两种选择 工作 在手机上切换方向时(是, onSaveInstanceState startActivity(Intent) onSaveInstanceState() 再一次。这一次,它失败了,原因我不知道。可疑的是 onSaveInstanceState() 执行成功。打印的堆栈跟踪没有指向我的任何代码:

    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)
    

    有没有办法在实例状态下存储自定义对象?

    5 回复  |  直到 16 年前
        1
  •  6
  •   Macarse    16 年前

    CustomObject 实施 Parcelable

    outState.putParcelable(KEY, myList);
    onSaveInstanceState(outState);
    

    同时检查 this 辅导的。

    编辑 在Commonware注释之后:

    Serializable 可包裹的

    • private void readObject(ObjectInputStream aStream) throws IOException, ClassNotFoundException { /*Your deserialization */ }
    • private void writeObject(ObjectOutputStream aStream) throws IOException { /*Your serialization */}
        2
  •  5
  •   CommonsWare    16 年前

    有你的 List<CustomObject>

    您不仅不必担心在实例状态下保留它,而且可以更好地控制内存中这些对象的生存期。实例状态生存期由Android控制;多长时间 Service 抓住物体是由你控制的。尤其是如果 CustomObject 可能很大,或者列表很长,我希望您能够更好地控制RAM的使用时间。

        3
  •  1
  •   adamp    16 年前

    如果这主要是为了处理方向的变化,可以 Activity#onRetainNonConfigurationInstance() 你想要什么?

    活动可以使用此API将广泛的状态从旧的活动实例传播到新的活动实例,从加载的位图传播到网络连接,再传播到均匀运行的线程。请注意,您不应该传播任何可能会根据配置而更改的数据,包括从字符串、布局或可绘制内容等资源加载的任何数据。

    如果您只是想在配置更改中持久化数据,那么这个API将帮不上什么忙。

        4
  •  0
  •   akjoshi HCP    13 年前

    据我所知, SavedInstanceState 用于保存活动的UI配置(如标准Android UI小部件,例如文本字段,会自动保存)。

    // maintain a reference to the EchoServer object when the activity is recreated
    @Override
    public Object onRetainNonConfigurationInstance() {
        return <<your object of choice>>;
    }
    

    在onCreate(Bundle savedInstanceState)方法中,可以检索对象:

        // if there is a saved instance state, restore the state
        if (savedInstanceState != null) {
            <<yourObject>> = (<<your object's class) getLastNonConfigurationInstance();
    
        5
  •  -2
  •   jjnguy Julien Chastang    15 年前

    为什么不把对象保存到SD卡上呢?您可以在我的博客中看到我如何使用此功能的示例>&燃气轮机; http://androidworkz.com/2010/07/06/source-code-imageview-flipper-sd-card-scanner/

    public void saveArray(String filename, String[] output_field) {
             try {
                FileOutputStream fos = new FileOutputStream(filename);
                GZIPOutputStream gzos = new GZIPOutputStream(fos);
                ObjectOutputStream out = new ObjectOutputStream(gzos);
                out.writeObject(output_field);
                out.flush();
                out.close();
             }
             catch (IOException e) {
                 e.getStackTrace(); 
             }
          }
    
        public String[] loadArray(String filename) {
              try {
                FileInputStream fis = new FileInputStream(filename);
                GZIPInputStream gzis = new GZIPInputStream(fis);
                ObjectInputStream in = new ObjectInputStream(gzis);
                String[] read_field = (String[])in.readObject();
                in.close();
                return read_field;
              }
              catch (Exception e) {
                  e.getStackTrace();
              }
              return null;
          }
    
    推荐文章