如何在Parcel中使用writeStringArray()和readStringArray()

时间:2013-01-17 18:00:07

标签: java android marshalling parcelable parcel

我最近在Androids Parcel类中遇到了一个非常愚蠢的(至少从我的角度来看)实现。

假设我有一个像这样的简单类

class Foo implements Parcelable{

    private String[] bars;
    //other members

    public in describeContents(){ 
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags){

        dest.writeStringArray(bars);
        //parcel others
    }

    private Foo(Parcel source){
        source.readStringArray(bars);
        //unparcel other members
    }

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

         public Foo createFromParcel(Parcel source){
             return new Foo(source);
         }

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

    };
}

现在,如果我想要Parcel Foo对象而bars为空,我认为没有办法从这种情况中恢复(当然是捕获异常的例子)。以下是Parcel中这两种方法的实现:

 public final void writeStringArray(String[] val) {
        if (val != null) {
            int N = val.length;
            writeInt(N);
            for (int i=0; i<N; i++) {
                writeString(val[i]);
            }
        } else {
            writeInt(-1);
        }
    }


  public final void readStringArray(String[] val) {
        int N = readInt();
        if (N == val.length) {
            for (int i=0; i<N; i++) {
                val[i] = readString();
            }
        } else {
            throw new RuntimeException("bad array lengths");
        }
    }

因此,如果我传递空的bars,则writeStringArray就可以了。它只是将-1写入包裹。但是readStringArray方法应该如何使用呢?如果我在内部传递bars(当然是null),我将从val.length获得NullPointerException。如果我之前创建bars,就像说bars = new String[???]一样,我不知道应该有多大。如果大小与内部写的不匹配,我会收到RuntimeException。

为什么readStringArray不知道-1的结果是从writeStringArray写入空对象而只是返回?

我看到的唯一方法是在调用bars之前保存writeStringArray(String[])的大小,这会使这种方法变得毫无用处。它还将冗余地保存数组的大小两次(一次让我记住,第二次来自writeStringArray)。

有没有人知道如何使用这两种方法,因为它们上面没有java-doc?

2 个答案:

答案 0 :(得分:30)

您应该在案件中使用Parcel.createStringArray()

我无法想象Parcel.readStringArray(String[] val)的正确用例,但为了使用它,你必须知道数组的确切大小并手动分配它。

答案 1 :(得分:4)

从(缺少)文档中不是很清楚,但是当对象在调用此函数之前已经知道如何创建字符串数组时,将使用readStringArray();例如,当它在统计上实例化时,或者从另一个先前读取的值中知道它的大小。

这里你需要的是调用函数createStringArray()