アクティビティにカスタムオブジェクトのリストを渡すためにArrayList
Parcelable
を作成しようとしています。私はArrayList<myObject>
を拡張するmyObjectList
クラスを書き始め、Parcelable
を実装します。
MyObject
の一部の属性はboolean
ですが、Parcel
にはメソッドread/writeBoolean
がありません。
これを処理するための最良の方法は何ですか?
これが私のやり方です….
writeToParcel:
dest.writeByte((byte) (myBoolean ? 1 : 0)); //if myBoolean == true, byte == 1
readFromParcel:
myBoolean = in.readByte() != 0; //myBoolean == true if byte != 0
writeValue メソッドを利用することもできます。私の意見では、それが最も簡単な解決策です。
dst.writeValue( myBool );
その後はBoolean
への単純なキャストで簡単に取得できます。
boolean myBool = (Boolean) source.readValue( null );
内部ではAndroidフレームワークはそれを整数として扱います。
writeInt( (Boolean) v ? 1 : 0 );
あなたはこのように宣言する
private boolean isSelectionRight;
書きます
out.writeInt(isSelectionRight ? 1 : 0);
読む
isSelectionRight = (in.readInt() == 0) ? false : true;
ブール型は、Parcelがサポートするものに変換する必要があるので、それをintに変換できます。
AndroidStudio(2.3 atmを使用)では、クラスにParcelableを実装した後、クラス名の上にマウスポインタを置くだけで、追加するように求められます。解析可能な実装
4つのフィールドから、次のものが生成されます。
public class YourClass implements Parcelable{
String someString;
int someInt;
boolean someBoolean;
List<String> someList;
protected YourClass(Parcel in) {
someString = in.readString();
someInt = in.readInt();
someBoolean = in.readByte() != 0;
someList = in.createStringArrayList();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(someString);
dest.writeInt(someInt);
dest.writeByte((byte) (someBoolean ? 1 : 0));
dest.writeStringList(someList);
}
...
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
私は通常それらを配列にしてwriteBooleanArray
とreadBooleanArray
を呼び出します
それがあなたがパックする必要がある単一のブール値であるならば、あなたはこれをすることができました:
parcel.writeBooleanArray(new boolean[] {myBool});
Android Studioを使用している場合、Parcelableを実装する最も簡単な方法をお勧めします。
単に[ファイル] - > [設定] - > [プラグイン] - > [リポジトリの参照]に移動し、解析可能なファイルを検索してください。
そしてこれをするためのウェブサイトもあります。 http://www.parcelabler.com/
NULL可能なサポートを伴う、Kotlinでの短くて簡単な実装:
Parcelにメソッドを追加する
fun Parcel.writeBoolean(flag: Boolean?) {
when(flag) {
true -> writeInt(1)
false -> writeInt(0)
else -> writeInt(-1)
}
}
fun Parcel.readBoolean(): Boolean? {
return when(readInt()) {
1 -> true
0 -> false
else -> null
}
}
そしてそれを使う:
parcel.writeBoolean(isUserActive)
parcel.readBoolean() // For true, false, null
parcel.readBoolean()!! // For only true and false
マスキングとシフトを使用して、ブール値を1バイトにパックできます。それがそれをするための最も効率的な方法でしょう、そしておそらく彼らはあなたがすることを期待するだろうものです。
ここで本当の問題を特定するのは難しいです。 Parcelable
インターフェースを実装するときにブール値を処理する方法であると思います。
MyObjectの一部の属性はブール値ですが、Parcelにはread/writeBooleanメソッドはありません。
値を文字列またはバイトとして格納する必要があります。あなたが文字列のために行くならば、あなたはブール値を解析するためにvalueOf()
と呼ばれるString
クラスの静的メソッドを使わなければなりません。それは1バイトタフでそれを保存するほど効果的ではありません。
String.valueOf(theBoolean);
あなたが少しバイトを取りに行けば、あなたは自分で変換ロジックを実装しなければならないでしょう。
byte convBool = -1;
if (theBoolean) {
convBool = 1;
} else {
convBool = 0;
}
Parcel
オブジェクトを非整列化するときは、元の型への変換に注意する必要があります。
あなたがあなた自身でそれをやりたいならば、この質問はすでに他の人々によって完全に答えられました。
低レベルのパーセルコードの大部分をカプセル化または非表示にしたい場合は、先ほど書いたコードの一部を 使用してパーセルの取り扱いを簡単にすることを検討してください。
区画への書き込みは、次のように簡単です。
parcelValues(dest, name, maxSpeed, weight, wheels, color, isDriving);
たとえば、colorはenum、isDrivingはブール値です。
区画からの読み取りもそれほど難しくありません。
color = (CarColor)unparcelValue(CarColor.class.getClassLoader());
isDriving = (Boolean)unparcelValue();
プロジェクトに追加した「ParceldroidExample」を見てください。
最後に、それはまたCREATOR初期化子を短くします:
public static final Parcelable.Creator<Car> CREATOR =
Parceldroid.getCreatorForClass(Car.class);
Android(AOSP)のソースには多くの例があります。たとえば、PackageInfo
クラスはブール型のメンバーrequiredForAllUsers
を持ち、次のようにシリアル化されます。
public void writeToParcel(Parcel dest, int parcelableFlags) {
...
dest.writeInt(requiredForAllUsers ? 1 : 0);
...
}
private PackageInfo(Parcel source) {
...
requiredForAllUsers = source.readInt() != 0;
...
}