Как использовать writeStringArray() и readStringArray() в посылке

Недавно я столкнулся с очень глупой (по крайней мере, с моей точки зрения) реализацией внутри класса 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 a Foo Object и bars был null, я не вижу возможности восстановить эту ситуацию (кроме, конечно, исключений для исключения). Вот реализация этих двух методов из 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");
        }
    }

Так что writeStringArray в порядке, если я передаю bars, которые являются нулевыми. Он просто пишет -1 на Посылку. Но как должен использоваться метод readStringArray? Если я пройду bars внутри (что, конечно, равно null), я получу исключение NullPointerException из val.length. Если я создаю bars, прежде чем скажу bars = new String[???], я не понимаю, насколько это должно быть. Если размер не совпадает с тем, что было написано внутри, я получаю исключение RuntimeException.

Почему readStringArray не знает результат -1, который записывается на нулевые объекты из writeStringArray и просто возвращает?

Единственный способ, который я вижу, - сохранить размер bars, прежде чем я вызову writeStringArray(String[]), что делает этот метод бесполезным. Он также повторно резервирует размер массива дважды (один раз для меня, чтобы помнить, второй раз из writeStringArray).

Кто-нибудь знает, как эти два метода должны использоваться, поскольку для них нет java-doc?

Ответ 1

Вы должны использовать Parcel.createStringArray() в своем случае.

Я не могу представить подходящий вариант использования Parcel.readStringArray(String[] val), но для его использования вы должны знать точный размер массива и вручную его распределять.

Ответ 2

Это не совсем понятно из документации (отсутствия), но readStringArray() следует использовать, когда объект уже знает, как создать массив строк перед вызовом этой функции; например, когда он статистически обусловлен или его размер известен из другого ранее прочитанного значения.

Здесь вам нужно вызвать функцию createStringArray().