正确实现Parcelable的方法

时间:2016-02-13 16:28:48

标签: android android-intent parcelable badparcelableexception

在Android中实现Parcelable界面的正确方法是什么?根据文档,您应该实现writeToParcel方法并拥有CREATOR

public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mData);
 }

但是当我实施它而没有添加CREATOR并将writeToParcel()留空时,应用仍然可以正常工作。有时我会得到Bad Parcelable Exception,但我无法解决复制的步骤。

这是我用来将一个对象从activity传递到片段

的方法
 Bundle bundle = new Bundle();
 bundle.putParcelable(PageFragment.PAGE_FILTER_KEY, page);
 fragment.setArguments(bundle);

那么,添加像out.writeInt(mData);这样的东西的目的是什么呢?如果不这样做,可以预期会出现什么样的问题?

2 个答案:

答案 0 :(得分:4)

Parcelable实现主要有两个流程步骤。

1将您的java对象编写为包含两种方法的Parcel

  @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(cityName);
        dest.writeString(macroName);
        dest.writeString(id);
    }

其中describe内容用于为您的内容设置标志。大多数时候你只需要它不受影响。

public void writeToParcel(Parcel dest,int flags),您需要根据JAVA类中的字段逐步将Java类对象写入parcel。在上面的例子中,我的类有三个字符串。您可以在parcel中编写几乎所有类型的对象。你只需要选择合适的一个。像writeString(),writeList()或writeObject()等。

<强> 2。第二部分是从包裹中读取你的java对象

这部分还需要两件事。首先是你的java类的CREATOR,如下面的

 public static final Creator<City> CREATOR = new Creator<City>() {
        @Override
        public City createFromParcel(Parcel in) {
            return new City(in);
        }

        @Override
        public City[] newArray(int size) {
            return new City[size];
        }
    };

在上面的示例中,我的Java类是City。它使得从包裹中读取城市对象。但它调用了 City 类的新City(in)构造函数。所以现在我需要一个构造函数来接受参数中的parcel对象。让我们创造它......

 protected City(Parcel in) {
        cityName = in.readString();
        macroName = in.readString();
        id = in.readString();
    }

现在我们制作一个完整的完整证明类。需要注意的一点是,我们需要在受保护的城市(包裹)中以相同的顺序读取成员,我们将它们放在包裹中,即在writeToParcel()方法中。

关于如何通过简单地让android从parcelable创建java对象来重现badParcelable exeption。为此你可以从android设备上的开发者选项中选择Destroy活动,并将你的应用程序放在该活动的后台,所以android会杀死你的应用程序进程ID。通过重新创建活动来恢复您的应用程序(onCreate + Bundle),如果您没有正确实现parcelable,您将获得该异常。

答案 1 :(得分:2)

  

但是当我实现它而不添加CREATOR并将writeToParcel()留空时,应用程序似乎仍能正常工作。

CREATOR读取数据并将其转换回对象时,使用

Parcel

writeToParcel()将您的数据放入Parcel

如果您的Parcelable实际上没有被放入Parcel或从Parcel重新构建,那么将其关闭的唯一方法就是正常工作。示例包括LocalBroadcastManager

  

添加out.writeInt(mData);

等内容的目的是什么?

out.write()之类的内容添加到OutputStream中的目的与此相同:它会写入输出。你的问题类似于问“嘿,如果我不把数据写入我的档案,我会遇到什么样的问题?”。