java Android:永远不会调用 Parcelable.writeToParcel 和 Parcelable.Creator.createFromParcel

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4853952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:20:28  来源:igfitidea点击:

Android: Parcelable.writeToParcel and Parcelable.Creator.createFromParcel are never called

javaandroidbundleparcelable

提问by AD-Venture

I'm totally new to posting questions on here, however I have been reading a lot on here for years. Normally I always am able to find my answers by thoroughly searching the web, but this time I am at a loss...

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

After having spent yet another day of trying to figure out why this is not working I decided to ask for help, hoping you guys can give me a few pointers, or better, a solution.

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

The problem: In an Android game I have come to the point where I have to make the application remember its state when a user e.g. presses the HOME-screen button. After some searches I realised that in order to make my classes initialize back to their appropriate states after re-opening the application I had to support the Parcelable interface to pass them with the Bundle.

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

In my onStop and onStart functions I respectively save and restore the game state to and from a Bundle, however when I call the putParcelable and getParcelable functions on the Bundle the object's writeToParcel and createFromParcel functions are never called.

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

Fearing that this may have been due to the relative complexity of the game I figured I had best create a very simple application to try to get it to work.

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

Based on many Parcelable examples I have seen online, this became my class:

根据我在网上看到的许多 Parcelable 示例,这成为了我的课程:

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];
      }
  };
}

And from my Main activity I would call the following functions to save / restore the data:

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

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");

    }

But for some reason neither of the functions (with the putParcelable and getParcelable functions) will result in the appropriate Parcelable calls in my test class.

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

The strangest thing is that it does somehow read the correct values (I have tried with more variables in the class), but my debugging and my log shows that tha application never gets to writeToParcel and createFromParcel.

最奇怪的是它确实以某种方式读取了正确的值(我在类中尝试了更多变量),但是我的调试和日志显示该应用程序永远无法访问 writeToParcel 和 createFromParcel。

What am I missing here?

我在这里错过了什么?

Any help / thoughts would be appreciated.

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

回答by superjos

Apparently the Android Bundle class does not adhere to the parcelable protocolthat instead is followed during IPC marshalling.

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

Instead, it seems like the Bundle implementation just writes and reads the Parcelable object into its own internal map by means of reflection. From a test we did, it seems that the Bundle writes/reads every field defined in your Parcelable-derived class, just because you have declared those fields.

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

回答by Luis

Technically, the documentation doesn't say that writeToParcelor createFromParcelare called from onSaveInstance. As a matter of fact, if you check the savedStatein your code you are going to find that it is exactly the same object instance in both the save and the restore cases; it makes sense to avoid serialize-deserialize if you can.
OTOH, the documentation doesn't say either that serialization is not done. The conclusion should be that you shouldn't depend on either case, just assume that you get the correct bundle.

从技术上讲,文档并没有这么说writeToParcelcreateFromParcelonSaveInstance. 事实上,如果你检查savedState你的代码,你会发现它在保存和恢复情况下都是完全相同的对象实例;如果可以,避免序列化-反序列化是有意义的。
OTOH,文档也没有说没有完成序列化。结论应该是你不应该依赖任何一种情况,只要假设你得到了正确的包。

Also, you may want to check http://developer.android.com/guide/topics/resources/runtime-changes.html

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

回答by existenz31

I confirm what superjos said. On the saveToBundle event, Android bundle just stores the class's members per reflection and doesn't call the Parcelable functions. I have lost one day on this problem! sad....

我证实了 superjos 所说的。在 saveToBundle 事件中,Android bundle 只存储每个反射的类成员,不调用 Parcelable 函数。我已经在这个问题上迷失了一天!伤心....

This is really bad .... This means you potentially stores a huge amount of data for nothing using this way.

这真的很糟糕......这意味着您可能会使用这种方式存储大量数据。