Parcelable 객체 배열 읽기 및 쓰기
소포에서 객체 배열을 읽고 쓰는 다음 클래스가 있습니다.
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
.
오류 / 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를 던지는 이유는 무엇입니까?
다음 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);
}
오류 / AndroidRuntime (5880) : 원인 : java.lang.ClassCastException : [Landroid.os.Parcelable;
API 에 따르면 readParcelableArray 메서드는 Parcelable 배열 (Parcelable [])을 반환하는데, 이는 단순히 MyClass 배열 (MyClass [])로 캐스팅 할 수 없습니다.
하지만 이제 Null Pointer Exception이 발생합니다.
자세한 예외 스택 추적없이 정확한 원인을 알 수 없습니다.
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);
}
비슷한 문제가 있었는데 이렇게 해결했습니다. Parcelable 배열을 MyClass 개체 배열로 변환하기 위해 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);
}
다음 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);
}
참고 URL : https://stackoverflow.com/questions/10071502/read-writing-arrays-of-parcelable-objects
'Program Tip' 카테고리의 다른 글
Maven 로컬 리포지토리 위치를 얻는 방법은 무엇입니까? (0) | 2020.10.20 |
---|---|
특정 위치의 ArrayList에 개체를 삽입하는 방법 (0) | 2020.10.20 |
StringDictionary 대 사전 (0) | 2020.10.20 |
앱이 컴퓨터에 연결되지 않은 상태에서 디버거를 기다리는 이유는 무엇입니까? (0) | 2020.10.20 |
C #에서 익명 유형을 키 / 값 배열로 변환합니까? (0) | 2020.10.20 |