【问题标题】:How to make a class with nested objects Parcelable如何使具有嵌套对象的类 Parcelable
【发布时间】:2013-01-06 02:38:59
【问题描述】:

我想让 A 类 Parcelable。

public class A {
    public String str;
    public ArrayList<B> list;
}

这是我到目前为止所想出的。但是它会因 NullPointerException 而崩溃。问题在于这两条语句:dest.writeList(list); & in.readList(list, this.getClass().getClassLoader());。 我不知道从这里做什么:(

A 类

public class A implements Parcelable {
    public String str;
    public ArrayList<B> list;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
        dest.writeList(list);
    }

    private A(Parcel in) {
        str = in.readString();
        in.readList(list, this.getClass().getClassLoader());
    }

    public static final Parcelable.Creator<A> CREATOR
            = new Parcelable.Creator<A>() {
        public A createFromParcel(Parcel in) {
            return new A(in);
        }

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

B 类

public class B implements Parcelable {
    public String str;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

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

    private B(Parcel in) {
        str = in.readString();
    }

    public static final Parcelable.Creator<B> CREATOR
            = new Parcelable.Creator<B>() {
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

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

感谢您的宝贵时间。

【问题讨论】:

    标签: android parcelable


    【解决方案1】:

    我终于知道要在 Google 中输入什么了 :),并找到了这个 Android, How to use readTypedList method correctly in a Parcelable class?

    解决方案是改用read-/writeTypedList。我还初始化了 arraylist 以避免任何进一步的 NullPointerException。

    A类

    public class A implements Parcelable {
        public String str;
        public ArrayList<B> list = new ArrayList<B>();
    
        @Override
        public int describeContents() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(str);
            dest.writeTypedList(list);
        }
    
        private A(Parcel in) {
            str = in.readString();
            in.readTypedList(list, B.CREATOR);
        }
    
        public static final Parcelable.Creator<A> CREATOR
                = new Parcelable.Creator<A>() {
            public A createFromParcel(Parcel in) {
                return new A(in);
            }
    
            public A[] newArray(int size) {
                return new A[size];
            }
        };
    }
    

    B 类

    public class B implements Parcelable {
        public String str;
    
        @Override
        public int describeContents() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(str);
        }
    
        private B(Parcel in) {
            str = in.readString();
        }
    
        public static final Parcelable.Creator<B> CREATOR
                = new Parcelable.Creator<B>() {
            public B createFromParcel(Parcel in) {
                return new B(in);
            }
    
            public B[] newArray(int size) {
                return new B[size];
            }
        };
    }
    

    【讨论】:

    • 啊,是的,它不让我,然后我有点忘了它:)
    • @Snæbjørn 感谢分享解决方案
    • @Snæbjørn +1 展示了如何创建一个包含非原始或自定义类型的 parcelable 类。
    • 很棒的例子。我可以建议您修复两个类中“AcreateFromParcel”函数的名称吗?在 A 类中应该是“public A createFromParcel”(缺少空格),在 B 类中应该是“public B createFromParcel”。是的,这很简单,但对于新手来说可能会很麻烦。
    【解决方案2】:

    如果您的主要 Parcelable 对象内只有一个 Parcelable 对象,则不要像接受的答案案例那样列出。然后会是这样的:

    A 类

    public class A implements Parcelable {
        public String str;
        public B objectB;
    
        @Override
        public int describeContents() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            //The parcelable object has to be the first one
            dest.writeParcelable(objectB, flags);
            dest.writeString(str);
        }
    
        private A(Parcel in) {
            this.objectB = in.readParcelable(B.class.getClassLoader());
            str = in.readString();
        }
    
        public static final Parcelable.Creator<A> CREATOR
                = new Parcelable.Creator<A>() {
            public A createFromParcel(Parcel in) {
                return new A(in);
            }
    
            public A[] newArray(int size) {
                return new A[size];
            }
        };
    }
    

    B 类

    public class B implements Parcelable {
        public String str;
    
        @Override
        public int describeContents() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(str);
        }
    
        private B(Parcel in) {
            str = in.readString();
        }
    
        public static final Parcelable.Creator<B> CREATOR
                = new Parcelable.Creator<B>() {
            public B createFromParcel(Parcel in) {
                return new B(in);
            }
    
            public B[] newArray(int size) {
                return new B[size];
            }
        };
    }
    

    重要提示: 请注意,您编写和读取Parcelable 对象的顺序很重要。查看此answer 了解更多详情

    【讨论】:

      【解决方案3】:

      在写包裹时

      @Override
      public void writeToParcel(Parcel parcel, int i) {
          parcel.writeString(name); //if String
          parcel.writeTypedList(assignedEmployees); //if List with custom class, eg. List<AssignedEmployee> assignedEmployees
          parcel.writeParcelable(checkin,i); //if custom class, eg. Checkin checkin;
          }
      

      在构造函数中读取它

       protected A(Parcel in) {
              name = in.readString();
              assignedEmployees = in.createTypedArrayList(AssignedEmployee.CREATOR);
              checkin = in.readParcelable(Checkin.class.getClassLoader());
          }
      

      在哪里 AssignedEmployee,在哪里签入自定义类,它应该实现 Parcelable。

      【讨论】:

        【解决方案4】:

        只需按 ALT+ENTER 并替换 Parcelable 它将实现所有必要的实现

        【讨论】:

        • 试试这个答案它会自动完成所有工作您不必编写任何代码。
        【解决方案5】:

        您可以从 prefs 添加 Parcelable 代码生成器插件,从那里您可以通过执行以下操作创建 Parcelable 样板代码: - 右键单击​​模型中的类名 - 选择生成 - 选择 Parcelable

        presto - 您的模型将使用必要的 Parcelable 样板代码进行更新。

        【讨论】:

          【解决方案6】:

          我遇到了同样的问题,generic version

          class Item<T : Parcelable> (val model: T, val index: Int ) : Parcelable {
          
              constructor(parcel: Parcel) :
                  this(parcel.readParcelable(
                    Item<T>::model.javaClass.classLoader),
                    parcel.readInt()
                  ) {}
          
              override fun writeToParcel(parcel: Parcel?, flag: Int) {
                  parcel?.writeParcelable(model, 0)
                  parcel?.writeInt(index)
              }
          
              override fun describeContents(): Int {
                  return 0
              }
          
              companion object CREATOR : Parcelable.Creator<Item<Parcelable>> {
                  override fun createFromParcel(parcel: Parcel): Item<Parcelable> {
                      return Item(parcel)
                  }
          
                  override fun newArray(size: Int): Array<Item<Parcelable>?> {
                      return arrayOfNulls(size)
                  }
              }
          }
          

          【讨论】:

            【解决方案7】:

            不幸的是,我正在使用无法打包的第 3 方库中的一个类 (BarEntry)。我通过传递Intent 一个floats 数组解决了我的问题,然后在接收端重建我的BarEntry 对象。

            这是次优的,但如果有人遇到类似的情况,即无法创建可打包对象,这可能是一个有用的过程。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-01-09
              • 2012-10-08
              • 1970-01-01
              • 1970-01-01
              • 2022-08-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多