我有以下类读取和从/到一个包裹写入对象的数组:
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];
}
};
}
在上面的代码中,我得到一个ClassCastException
读取时readParcelableArray
:
ERROR / AndroidRuntime(5880):java.lang.ClassCastException:致[Landroid.os.Parcelable;
什么是错在上面的代码? 在写对象数组,我应该首先将数组转换成一个ArrayList
?
更新:
是否确定对象数组转换为一个ArrayList
,并将其添加到包裹? 例如,当写:
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?
Answer 1:
你需要使用写阵列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);
}
Answer 2:
ERROR / AndroidRuntime(5880):java.lang.ClassCastException:致[Landroid.os.Parcelable;
根据API ,readParcelableArray方法返回Parcelable阵列(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);
}
Answer 3:
我有一个类似的问题,并解决了这种方式。 我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的对象parcelable阵列,例如从一个意图:
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);
}
Answer 4:
你需要使用写阵列Parcel.writeTypedArray()
方法,并与读回Parcel.readTypedArray()
方法,像这样:
MyClass[] mObjArray;
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mObjArray.length);
out.writeTypedArray(mObjArray, flags);
}
protected MyClass(Parcel in) {
int size = in.readInt();
mObjArray = new MyClass[size];
in.readTypedArray(mObjArray, MyClass.CREATOR);
}
对于列表,您可以执行以下操作:
ArrayList<MyClass> mObjList;
public void writeToParcel(Parcel out, int flags) {
out.writeTypedList(mObjList);
}
protected MyClass(Parcel in) {
mObjList = new ArrayList<>(); //non-null reference is required
in.readTypedList(mObjList, MyClass.CREATOR);
}
文章来源: Read & writing arrays of Parcelable objects