web-dev-qa-db-ja.com

ArrayList <Parcelable>でParcelableを適切に実装する方法は?

クラスParcelableの作成に問題があります。問題は、ArrayList<Parcelable>オブジェクトであるクラスのメンバーをパーセルに書き込もうとしていることです。 ArrayListSerializableであり、リスト内のオブジェクト(ZigBeeDev)はParcelableです。

関連するコードは次のとおりです。

package com.gnychis.coexisyst;

import Java.util.ArrayList;
import Java.util.Iterator;

import Android.os.Parcel;
import Android.os.Parcelable;

public class ZigBeeNetwork implements Parcelable {

    public String _mac;             // the source address (of the coordinator?)
    public String _pan;             // the network address
    public int _band;               // the channel
    ArrayList<Integer> _lqis;       // link quality indicators (to all devices?)
    ArrayList<ZigBeeDev> _devices;  // the devices in the network

    public void writeToParcel(Parcel out, int flags) {
        out.writeString(_mac);
        out.writeString(_pan);
        out.writeInt(_band);
        out.writeSerializable(_lqis);
        out.writeParcelable(_devices, 0);  // help here
    }

    private ZigBeeNetwork(Parcel in) {
        _mac = in.readString();
        _pan = in.readString();
        _band = in.readInt();
        _lqis = (ArrayList<Integer>) in.readSerializable();
        _devices = in.readParcelable(ZigBeeDev.class.getClassLoader());  // help here
    }

    public int describeContents() {
        return this.hashCode();
    }

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

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

    //...
}

パーセルに適切に書き込む方法と再構築する方法を理解するために、「//ここで役立つ」という2つのスポットをマークしました。 ZigBeeDevParcelable(適切にテスト済み)の場合、これを適切に行うにはどうすればよいですか?

75
gnychis

あなたはほとんどそれを手に入れました!

あなたはただする必要があります:

public void writeToParcel(Parcel out, int flags) {
    out.writeString(_mac);
    out.writeString(_pan);
    out.writeInt(_band);
    out.writeSerializable(_lqis);
    out.writeTypedList(_devices);
}

private ZigBeeNetwork(Parcel in) {
    _mac = in.readString();
    _pan = in.readString();
    _band = in.readInt();
    _lqis = (ArrayList<Integer>) in.readSerializable();
    in.readTypedList(_devices, ZigBeeDev.CREATOR);
}

それで全部です!

整数のリストについては、次のこともできます。

out.writeList(_lqis);
_lqis = new ArrayList<>();
in.readList(_lqis Integer.class.getClassLoader());

動作するはずです。

141
NitroG42

私の場合、in.readTypedList(_devices, ZigBeeDev.CREATOR);_devicesNullPointerExceptionをくれました。だから私はこれを使用しました:

_devices = in.createTypedArrayList(ZigBeeDev.CREATOR);
17
osrl

整数のリストには writeList(List l) を使用し、ZigBeeDevicesのリストには writeTypedList(List val) を使用する必要があります

8
DoubleMalt

コンストラクタで使用する必要があります

_lqis = in.createTypedArrayList(ZigBeeDev.CREATOR);

そして、「writeToParcel」で使用します

out.writeTypedList(_lqis);
2
Anton Smirnov

少し遅れましたが、この問題もありました。長い時間の無駄の後、私は parcelabler.com のウェブサイトを見つけました。これは自動的に小包を作成します。

配列リストを含むネストされた区画を非常に簡単に作成でき、時間を大幅に節約できました。

基本的に、Webサイトの動作方法は、ArrayListを含むオブジェクトを入力すると、それをパーセル化するために必要なメソッドを自動的に追加します(パーセルからの読み取り、パーセルへの書き込み、コンテンツの説明、パーセルCreatorはすべて自動的に生成されます)。これは、ネストされたパーセル、配列、リストを含む、ここでの質問のような複雑なパーセルを作成するときに特に役立ちます。

編集: IntelliJ IDEA およびAndroid Studioには、リストされているWebサイトと同様のことを行うプラグインがあります:

これらのプラグインは、クラスのフィールドに基づいてAndroid Parcelable ボイラープレートコードを生成します。

0
JFreeman