简体   繁体   English

如何创建可包裹物品的二维可包裹物品数组?

[英]How to create a two dimensional parcelable array of parcelables?

I have to following parcelable object: 我必须遵循以下可包裹对象:

    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];
        }
    };
}

I want to create a two dimensional parcelable array of those objects in order to store it in the shared preferences for configuration changes. 我想为这些对象创建一个二维可拆分数组,以便将其存储在配置更改的共享首选项中。 this is what being generated by the parcelable android studio plugin: 这是可打包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];
        }
    };
}

Which is not accepted by the compiler because obviously it not correct. 编译器不接受哪个,因为显然它不正确。

What would be the correct right way to create this parcelable? 创建此包裹的正确正确方法是什么?

First, I will warn that there is a very strict size limit of 1 MB when transferring parcelables around. 首先,我警告说,周围传送包裹时必须严格限制大小为1 MB。 If you do a double array like this, then I can imagine it will be very easy to hit that limit and cause a crash. 如果您这样做是双重数组,那么我可以想象达到该限制并导致崩溃非常容易。

Anyway, to answer the question. 无论如何,要回答这个问题。 You can put absolutely anything you want in a Parcel object that is needed to recreate the object. 您可以将所需的任何东西绝对放入重新创建对象所需的Parcel对象中。 So in this case, you need to know the two dimensions of the array, and then just fill the array based on those dimensions. 因此,在这种情况下,您需要知道数组的两个维度,然后仅根据这些维度填充数组。 All that you have to do is ensure that the way you write them is exactly the same way you read them (which is the case for all parcelables). 您要做的就是确保编写它们的方式与阅读它们的方式完全相同(所有包裹都属于这种情况)。

One method would be to first write how many arrays are in your double array, then write each array. 一种方法是先写入双精度数组中有多少个数组,然后写入每个数组。

So in this case your writeToParcel will be something like this: 因此,在这种情况下,您的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);
   }
}

So now you know the very first int is the number of Card arrays in your double array. 所以现在您知道第一个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());
   }
}

Thanks to Deev 's answer, I moved in the right direction. 感谢Deev的回答,我朝着正确的方向前进。 However I faced a cast exception on this line: 但是我在这条线上遇到了强制转换例外:

(CGameCard[]) in.readParcelabeArray(CGameCard.class.getClassLoader());

To fix this, I finally use writeTypedArray and createTypedArray methods. 为了解决这个问题,我最终使用了writeTypedArraycreateTypedArray方法。 Here is below my working code: 这是我的工作代码下面:

Into the writeToParcel method of the GameCardArrArr class: 放入GameCardArrArr类的writeToParcel方法中:

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);
   }
}

In into the GameCardArrArr constructor with a Parcel as argument: Parcel作为参数进入GameCardArrArr构造函数:

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);
    }
}

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM