【问题标题】:Correct way of implementing ParcelableParcelable的正确实现方式
【发布时间】:2016-05-24 18:24:46
【问题描述】:

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

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

但是当我在不添加CREATOR 并将writeToParcel() 留空的情况下实现它时,应用程序似乎仍然可以正常工作。有时我会收到Bad Parcelable Exception,但我无法计算出复制的步骤。

这就是我用来将对象从活动传递到片段的方式

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

那么,添加out.writeInt(mData); 之类的东西的目的是什么?如果不这样做会出现什么样的问题?

【问题讨论】:

    标签: android android-intent parcelable badparcelableexception


    【解决方案1】:

    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 content 用于为您的内容设置标志。大多数时候你只需要保持原样。

    public void writeToParcel(Parcel dest, int flags) ,你需要根据JAVA类中的字段,一步一步编写你的Java类对象到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 类的 new City(in) 构造函数。所以现在我需要一个在参数中接受包裹对象的构造函数。让我们也创建它..

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

    现在我们使一个类完全完全证明可打包。需要注意的一点是,我们需要在 protected City(Parcel in) 中以相同的顺序读取成员,我们将它们放入 parcel 中,即在 writeToParcel() 方法中。

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

    【讨论】:

      【解决方案2】:

      但是当我在没有添加 CREATOR 并将 writeToParcel() 留空的情况下实现它时,应用程序似乎仍然可以正常工作。

      CREATOR 用于从Parcel 读回数据并将其转换回对象。

      writeToParcel() 将您的数据放入Parcel

      只有在你的Parcelable 没有真正放入Parcel 或从Parcel 重组的情况下才能正常工作。示例包括LocalBroadcastManager

      添加out.writeInt(mData);之类的东西的目的是什么

      这与添加 out.write()OutputStream 之类的内容相同:它会写入输出。您的问题类似于问“嘿,如果我不将数据写入文件,我会遇到什么样的问题?”。

      【讨论】:

      • 我在问题中添加了一个 sn-p,显示我如何使用 parcelable。能不能看一下,可能是我用的不对?
      • @AdrianHristov:最终,Bundle 可以放入Parcel 并跨进程边界传送。在这种情况下,我不确定何时。我们知道它会发生,就好像 Android 在您处于后台时终止了您的进程,但用户在离开后很快(例如 30 秒)返回到您的应用程序,我们的状态得到恢复,唯一可能的方法是如果我们的状态处于核心操作系统进程中(而不是刚刚终止的进程)。
      猜你喜欢
      • 2011-10-25
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      相关资源
      最近更新 更多