开发者

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

开发者 https://www.devze.com 2023-02-07 13:43 出处:网络
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

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开发者_StackOverflow 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.

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.

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:

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.

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.

What am I missing here?

Any help / thoughts would be appreciated.


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

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.


Technically, the documentation doesn't say that writeToParcel or createFromParcel are called from onSaveInstance. As a matter of fact, if you check the savedState in 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.

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


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....

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号