11

Parcel私は最近、Androidクラス内で非常に愚かな(少なくとも私の観点からは)実装に出くわしました。

このような単純なクラスがあるとします

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

    };
}

Fooここで、オブジェクトをパーセルしたいbarsがnullの場合、この状況から回復する方法がわかりません(もちろん例外をキャッチすることを除いて)。Parcelからのこれら2つのメソッドの実装は次のとおりです。

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

したがって、nullを渡す場合はwriteStringArrayで問題ありませんbars-1区画に書き込むだけです。しかし、メソッドreadStringArrayはどのように使用されることになっていますか?内部を通過barsすると(もちろんnullです)、からNullPointerExceptionが発生しval.lengthます。bars私が前に作成した場合、たとえばbars = new String[???]、それがどれほど大きくあるべきかについての手がかりは得られません。サイズが内部に書き込まれたものと一致しない場合、RuntimeExceptionを受け取ります。

なぜreadStringArray、その結果が-1nullオブジェクトに書き込まれ、writeStringArray返されるだけなのかわからないのですか?

私が見る唯一の方法は、bars呼び出す前にサイズを保存することwriteStringArray(String[])です。これにより、このメソッドは役に立たなくなります。また、配列のサイズを2回冗長に保存します(1回目は覚えておいて、2回目はからwriteStringArray)。

上にjava-docがないため、これら2つのメソッドがどのように使用されるかを知っている人はいますか?

4

2 に答える 2

34

あなたの場合に使用する必要がParcel.createStringArray()あります。

の適切な使用例を想像することはできませんParcel.readStringArray(String[] val)が、それを使用するには、配列の正確なサイズを知り、手動で割り当てる必要があります。

于 2013-01-17T18:06:18.423 に答える
5

ドキュメント(の欠如)からは明確ではありませんが、readStringArray()この関数を呼び出す前に、オブジェクトが文字列配列の作成方法をすでに知っている場合に使用されます。たとえば、統計的にインスタンス化されている場合や、以前に読み取った別の値からサイズがわかっている場合です。

ここで必要なのは、createStringArray()代わりに関数を呼び出すことです。

于 2013-01-17T18:37:52.103 に答える