首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >读写可打包对象的数组

读写可打包对象的数组
EN

Stack Overflow用户
提问于 2012-04-09 17:44:43
回答 4查看 73.1K关注 0票数 79

我有下面的类,它从包裹读取对象数组,或者将对象数组写入包裹:

class ClassABC extends Parcelable {
    MyClass[] mObjList;

    private void readFromParcel(Parcel in) {
        mObjList = (MyClass[]) in.readParcelableArray(
                com.myApp.MyClass.class.getClassLoader()));
    }

    public void writeToParcel(Parcel out, int arg1) {
        out.writeParcelableArray(mObjList, 0);
    }

    private ClassABC(Parcel in) {
        readFromParcel(in);
    }

    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<ClassABC> CREATOR =
            new Parcelable.Creator<ClassABC>() {

        public ClassABC createFromParcel(Parcel in) {
            return new ClassABC(in);
        }

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

在上面的代码中,我在读取readParcelableArray时得到一个ClassCastException

错误/AndroidRuntime(5880):由: java.lang.ClassCastException:[Landroid.os.Parcelable;

上面的代码有什么问题?在编写对象数组时,是否应该先将数组转换为ArrayList

更新:

是否可以将对象数组转换为ArrayList并将其添加到parcel?例如,当写下:

    ArrayList<MyClass> tmpArrya = new ArrayList<MyClass>(mObjList.length);
    for (int loopIndex=0;loopIndex != mObjList.length;loopIndex++) {
        tmpArrya.add(mObjList[loopIndex]);
    }
    out.writeArray(tmpArrya.toArray());

阅读时:

    final ArrayList<MyClass> tmpList = 
            in.readArrayList(com.myApp.MyClass.class.getClassLoader());
    mObjList= new MyClass[tmpList.size()];
    for (int loopIndex=0;loopIndex != tmpList.size();loopIndex++) {
        mObjList[loopIndex] = tmpList.get(loopIndex);
    }

但现在我有了NullPointerException。上面的方法正确吗?为什么会抛出一个NPE?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-28 15:51:05

您需要使用Parcel.writeTypedArray()方法编写数组,并使用Parcel.createTypedArray()方法读回它,如下所示:

MyClass[] mObjList;

public void writeToParcel(Parcel out) {
    out.writeTypedArray(mObjList, 0);
}

private void readFromParcel(Parcel in) {
    mObjList = in.createTypedArray(MyClass.CREATOR);
}

不应该使用readParcelableArray()/writeParcelableArray()方法的原因是,readParcelableArray()实际上会创建一个Parcelable[]。这意味着您不能将该方法的结果强制转换为MyClass[]。相反,您必须创建与结果长度相同的MyClass数组,并将结果数组中的每个元素复制到MyClass数组中。

Parcelable[] parcelableArray =
        parcel.readParcelableArray(MyClass.class.getClassLoader());
MyClass[] resultArray = null;
if (parcelableArray != null) {
    resultArray = Arrays.copyOf(parcelableArray, parcelableArray.length, MyClass[].class);
}
票数 163
EN

Stack Overflow用户

发布于 2012-04-09 19:14:10

错误/AndroidRuntime(5880):由: java.lang.ClassCastException:[Landroid.os.Parcelable;

根据API,readParcelableArray方法返回可打包数组(Parcelable[]),不能简单地转换为MyClass数组(MyClass[])。

,但现在我得到了空指针异常。

如果没有详细的异常堆栈跟踪,就很难说出确切的原因。

假设你已经让MyClass正确地实现了Parcelable,这就是我们通常序列化/反序列化parcelable对象数组的方式:

public class ClassABC implements Parcelable {

  private List<MyClass> mObjList; // MyClass should implement Parcelable properly

  // ==================== Parcelable ====================
  public int describeContents() {
    return 0;
  }

  public void writeToParcel(Parcel out, int flags) {
    out.writeList(mObjList);
  }

  private ClassABC(Parcel in) {
    mObjList = new ArrayList<MyClass>();
    in.readList(mObjList, getClass().getClassLoader());
   }

  public static final Parcelable.Creator<ClassABC> CREATOR = new Parcelable.Creator<ClassABC>() {
    public ClassABC createFromParcel(Parcel in) {
      return new ClassABC(in);
    }
    public ClassABC[] newArray(int size) {
      return new ClassABC[size];
    }
  };

}

希望这能有所帮助。

您还可以使用以下方法:

  public void writeToParcel(Parcel out, int flags) {
      out.writeTypedList(mObjList);
  }

  private ClassABC(Parcel in) {
      mObjList = new ArrayList<ClassABC>();
      in.readTypedList(mObjList, ClassABC.CREATOR);
  }
票数 37
EN

Stack Overflow用户

发布于 2013-04-10 14:49:37

我也有类似的问题,就这样解决了。我在MyClass中定义了一个帮助器方法,用于将Parcelable数组转换为MyClass对象数组:

public static MyClass[] toMyObjects(Parcelable[] parcelables) {
    MyClass[] objects = new MyClass[parcelables.length];
    System.arraycopy(parcelables, 0, objects, 0, parcelables.length);
    return objects;
}

每当我需要读取MyClass对象的可打包数组时,例如从一个意图读取:

MyClass[] objects = MyClass.toMyObjects(getIntent().getParcelableArrayExtra("objects"));

编辑:下面是我最近使用的同一函数的更新版本,以避免出现编译警告:

public static MyClass[] toMyObjects(Parcelable[] parcelables) {
    if (parcelables == null)
        return null;
    return Arrays.copyOf(parcelables, parcelables.length, MyClass[].class);
}
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10071502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档