我必须遵循parcelable对象:
public class CGameCard implements Parcelable {
...
private int mX;
private int mY;
private String mObjectName;
private int mState;
public CGameCard(int aX, int aY, String aObjectName) {
mX = aX;
mY = aY;
mObjectName = aObjectName;
mState = CARD_STATE_NOT_MATCHED;
}
public int getX() {
return mX;
}
public int getY() {
return mY;
}
public String getObjectName(){
return mObjectName;
}
public int getState() {
return mState;
}
...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mX);
dest.writeInt(this.mY);
dest.writeString(this.mObjectName);
dest.writeInt(this.mState);
}
protected CGameCard(Parcel in) {
this.mX = in.readInt();
this.mY = in.readInt();
this.mObjectName = in.readString();
this.mState = in.readInt();
}
public static final Creator<CGameCard> CREATOR = new Creator<CGameCard>() {
@Override
public CGameCard createFromParcel(Parcel source) {
return new CGameCard(source);
}
@Override
public CGameCard[] newArray(int size) {
return new CGameCard[size];
}
};
}
我想创建这些对象的二维可分隔数组,以便将其存储在共享首选项中以进行配置更改。 这是由parcelable android studio插件生成的:
public class GameCardArrArr implements Parcelable {
private CGameCard[][] mArray;
public GameCardArrArr(CGameCard[][] array) {
mArray = array;
}
public CGameCard[][] getArray() {
return mArray;
}
public void setArray(CGameCard[][] mArray) {
this.mArray = mArray;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(this.mArray, flags);
}
protected GameCardArrArr(Parcel in) {
this.mArray = in.readParcelable(CGameCard[][].class.getClassLoader());
}
public static final Creator<GameCardArrArr> CREATOR = new Creator<GameCardArrArr>() {
@Override
public GameCardArrArr createFromParcel(Parcel source) {
return new GameCardArrArr(source);
}
@Override
public GameCardArrArr[] newArray(int size) {
return new GameCardArrArr[size];
}
};
}
编译器不接受这一点,因为它显然不正确。
创建此parcelable的正确方法是什么?
答案 0 :(得分:2)
首先,我会警告在转移parcelables时,有一个非常严格的大小限制为1 MB。如果你像这样做一个双数组,那么我可以想象非常很容易达到这个限制并导致崩溃。
无论如何,要回答这个问题。您可以将所需的任何内容放在重新创建对象所需的Parcel对象中。因此,在这种情况下,您需要知道数组的两个维度,然后根据这些维度填充数组。您所要做的就是确保您编写它们的方式与读取它们的方式完全相同(所有parcelables都是如此)。
一种方法是首先编写双数组中有多少数组,然后编写每个数组。
因此,在这种情况下,您的writeToParcel
将是这样的:
void writeToParcel(Parcel dest, int flags) {
int numOfArrays = mArray.length;
dest.writeInt(numOfArrays); // save number of arrays
for (int i = 0; i < numOfArrays; i++) {
dest.writeParcelableArray(mArray[i], flags);
}
}
所以现在您知道第一个int
是双数组中的Card数组的数量。
GameCardArrArr(Parcel in) {
int numberOfArrays = in.readInt();
mArray = new CGameCard[numberOfArays][];
for (int i = 0; i < numberOfArrays; i++) {
mArray[i] = (CGameCard[]) in.readParcelabeArray(CGameCard.class.getClassLoader());
}
}
答案 1 :(得分:0)
感谢Deev的回答,我朝着正确的方向前进。但是我在这条线上遇到了一个强制转换的例外:
(CGameCard[]) in.readParcelabeArray(CGameCard.class.getClassLoader());
要解决此问题,我最终会使用writeTypedArray
和createTypedArray
方法。
这是我的工作代码:
进入writeToParcel
类的GameCardArrArr
方法:
public void writeToParcel(Parcel dest, int flags) {
int numOfArrays = mArray.length;
dest.writeInt(numOfArrays); // save number of arrays
for (int i = 0; i < numOfArrays; i++) {
dest.writeTypedArray(mArray[i] , flags);
}
}
进入GameCardArrArr
构造函数,其中Parcel
为参数:
protected GameCardArrArr(Parcel in) {
int numberOfArrays = in.readInt();
mArray = new CGameCard[numberOfArrays][];
for (int i = 0; i < numberOfArrays; i++) {
mArray[i] = in.createTypedArray(CGameCard.CREATOR);
}
}
希望有所帮助