Android: Parcelable.writeToParcel 和 Parcelable.Creator.createFromParcel 从不被调用

2022-09-01 21:21:01

我对在这里发布问题完全陌生,但是多年来我一直在这里阅读很多东西。通常情况下,我总是能够通过彻底搜索网络来找到我的答案,但这次我不知所措......

在又花了一天时间试图弄清楚为什么这不起作用之后,我决定寻求帮助,希望你们能给我一些指导,或者更好的解决方案。

问题:在Android游戏中,我已经到了必须让应用程序在用户(例如按下主屏幕按钮)时记住其状态的地步。经过一些搜索,我意识到,为了使我的类在重新打开应用程序后初始化回其适当的状态,我必须支持 Parcelable 接口才能将它们与 Bundle 一起传递。

在我的 onStop 和 onStart 函数中,我分别将游戏状态保存并恢复到捆绑包中,但是当我在 Bundle 上调用 putParcelable 和 getParcelable 函数时,对象的 writeToParcel 和 createFromParcel 函数永远不会被调用。

由于担心这可能是由于游戏的相对复杂性,我认为我最好创建一个非常简单的应用程序来尝试使其正常工作。

根据我在网上看到的许多可包裹的例子,这成为我的课程:

public class ParcelableTest implements Parcelable {
  int id;

  public ParcelableTest(int newID)
  {
    id = newID;
  }

  private ParcelableTest(Parcel in) {
      readFromParcel(in);
  }

  public void writeToParcel(Parcel out, int arg1) {
      writeToParcel(out);
  }

  public void writeToParcel(Parcel out) {
    Log.v("ParcelableTest","Writing to parcel");
      out.writeInt(id);
  }

  public void readFromParcel(Parcel in) {
      id = in.readInt();
  }

  public int describeContents() {
      return 0;
  }

  public static final Parcelable.Creator<ParcelableTest> CREATOR = new
  Parcelable.Creator<ParcelableTest>() {
      public ParcelableTest createFromParcel(Parcel in) {
          Log.v("ParcelableTest","Creating from parcel");
              return new ParcelableTest(in);
      }

      public ParcelableTest[] newArray(int size) {
              return new ParcelableTest[size];
      }
  };
}

从我的主要活动中,我会调用以下函数来保存/恢复数据:

public Bundle saveToBundle(Bundle savedState)
    {
      savedState.putParcelable("Test1",mTest1);
      savedState.putParcelable("Test2",mTest2);
      return savedState;
    }
    public void restoreFromBundle(Bundle savedState)
    {
      mTest1 = savedState.getParcelable("Test1");
      mTest2 = savedState.getParcelable("Test2");

    }

但是由于某种原因,这两个函数(使用 putParcelable 和 getParcelable 函数)都不会在我的测试类中产生适当的 Parcelable 调用。

最奇怪的是,它确实以某种方式读取了正确的值(我已经尝试在类中使用了更多的变量),但是我的调试和我的日志显示,应用程序永远不会写ToParcel并创建FromParcel。

我在这里错过了什么?

任何帮助/想法将不胜感激。


答案 1

显然,Android Bundle类不遵守在IPC编组期间遵循的可打包协议

相反,Bundle 实现似乎只是通过反射将 Parcelable 对象写入并读取到其自己的内部映射中。从我们所做的测试来看,Bundle 似乎会写入/读取 Parcelable 派生类中定义的每个字段,只是因为您已经声明了这些字段。


答案 2

从技术上讲,文档没有说或从 调用。事实上,如果您检查代码中的,您会发现它在保存和还原情况下都是完全相同的对象实例;如果可以的话,避免序列化-反序列化是有意义的。
OTOH,文档也没有说序列化没有完成。结论应该是你不应该依赖于任何一种情况,只要假设你得到了正确的捆绑包。writeToParcelcreateFromParcelonSaveInstancesavedState

此外,您可能需要检查 http://developer.android.com/guide/topics/resources/runtime-changes.html


推荐