web-dev-qa-db-ja.com

ネストされたオブジェクトを含むクラスをParcelableにする方法

クラスAをパーセル可能にします。

_public class A {
    public String str;
    public ArrayList<B> list;
}
_

これは私がこれまでに思いついたことです。ただし、NullPointerExceptionでクラッシュします。問題は次の2つのステートメントです:dest.writeList(list);in.readList(list, this.getClass().getClassLoader());。私はここから何をすべきか分かりません:(

クラスA

_public class A implements Parcelable {
    public String str;
    public ArrayList<B> list;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
        dest.writeList(list);
    }

    private A(Parcel in) {
        str = in.readString();
        in.readList(list, this.getClass().getClassLoader());
    }

    public static final Parcelable.Creator<A> CREATOR
            = new Parcelable.Creator<A>() {
        public A createFromParcel(Parcel in) {
            return new A(in);
        }

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

クラスB

_public class B implements Parcelable {
    public String str;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
    }

    private B(Parcel in) {
        str = in.readString();
    }

    public static final Parcelable.Creator<B> CREATOR
            = new Parcelable.Creator<B>() {
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

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

お時間をいただきありがとうございます。

37
Snæbjørn

私は最終的にGoogleに入力するものを見つけました:)、これを見つけました Android、ParcelableクラスでreadTypedListメソッドを正しく使用する方法?

解決策はread-/writeTypedList代わりに。さらにNullPointerExceptionを回避するために、arraylistを初期化します。

クラスA

public class A implements Parcelable {
    public String str;
    public ArrayList<B> list = new ArrayList<B>();

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
        dest.writeTypedList(list);
    }

    private A(Parcel in) {
        str = in.readString();
        in.readTypedList(list, B.CREATOR);
    }

    public static final Parcelable.Creator<A> CREATOR
            = new Parcelable.Creator<A>() {
        public A createFromParcel(Parcel in) {
            return new A(in);
        }

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

クラスB

public class B implements Parcelable {
    public String str;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
    }

    private B(Parcel in) {
        str = in.readString();
    }

    public static final Parcelable.Creator<B> CREATOR
            = new Parcelable.Creator<B>() {
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

        public B[] newArray(int size) {
            return new B[size];
        }
    };
}
54
Snæbjørn

メインのParcelableオブジェクト内にParcelableオブジェクトが1つしかない場合は、受け入れられた回答ケースのようにリストしないでください。その後、次のようになります。

クラスA

public class A implements Parcelable {
    public String str;
    public B objectB;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        //The parcelable object has to be the first one
        dest.writeParcelable(objectB, flags);
        dest.writeString(str);
    }

    private A(Parcel in) {
        this.objectB = in.readParcelable(B.class.getClassLoader());
        str = in.readString();
    }

    public static final Parcelable.Creator<A> CREATOR
            = new Parcelable.Creator<A>() {
        public A createFromParcel(Parcel in) {
            return new A(in);
        }

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

クラスB

public class B implements Parcelable {
    public String str;

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(str);
    }

    private B(Parcel in) {
        str = in.readString();
    }

    public static final Parcelable.Creator<B> CREATOR
            = new Parcelable.Creator<B>() {
        public B createFromParcel(Parcel in) {
            return new B(in);
        }

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

重要:Parcelableオブジェクトの書き込みと読み取りの順序が重要であることに注意してください。詳細はこちら answer

26
Sami Eltamawy

小包への書き込み時

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(name); //if String
    parcel.writeTypedList(assignedEmployees); //if List with custom class, eg. List<AssignedEmployee> assignedEmployees
    parcel.writeParcelable(checkin,i); //if custom class, eg. Checkin checkin;
    }

それを読み返すコンストラクタで

 protected A(Parcel in) {
        name = in.readString();
        assignedEmployees = in.createTypedArrayList(AssignedEmployee.CREATOR);
        checkin = in.readParcelable(Checkin.class.getClassLoader());
    }

ここで、AssignedEmployee、Checkin、カスタムクラスとそれがParcelableを実装する必要があります。

2
Ebin Joy

残念ながら、パーセル化できないサードパーティライブラリのクラス(BarEntry)を使用していました。 Intentの配列をfloatsに渡し、受信側でBarEntryオブジェクトを再構築することで問題を解決しました。

これは最適とは言えませんが、同様の状況でパーセル可能なオブジェクトを作成できない場合は、有効なプロセスになる可能性があります。

0
JFreeman

Alt + Enterキーを押してParcelableを置き換えるだけで、必要なすべての実装が実装されます

0
Dhruv Singh

同じ問題がここにあります 汎用バージョン

class Item<T : Parcelable> (val model: T, val index: Int ) : Parcelable {

    constructor(parcel: Parcel) :
        this(parcel.readParcelable(
          Item<T>::model.javaClass.classLoader),
          parcel.readInt()
        ) {}

    override fun writeToParcel(parcel: Parcel?, flag: Int) {
        parcel?.writeParcelable(model, 0)
        parcel?.writeInt(index)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Item<Parcelable>> {
        override fun createFromParcel(parcel: Parcel): Item<Parcelable> {
            return Item(parcel)
        }

        override fun newArray(size: Int): Array<Item<Parcelable>?> {
            return arrayOfNulls(size)
        }
    }
}
0
Jocky Doe

設定からParcelableコードジェネレータプラグインを追加できます。そこから、次のようにしてParcelableボイラープレートコードを作成できます。-モデル内のクラス名を右クリック-select generate-select Parcelable

presto-モデルは必要なParcelableボイラープレートコードで更新されます。

0
GordonW