web-dev-qa-db-ja.com

カスタムオブジェクトをParcelableにするにはどうすればよいですか。

私は自分のオブジェクトをParcelableにしようとしています。しかし、私はカスタムオブジェクトを持っており、それらのオブジェクトは私が作った他のカスタムオブジェクトのArrayList属性を持っています。

これを行うための最良の方法は何でしょうか。

326
Jean Jimenez

これのいくつかの例 はこちらはこちら(コードはこちら) 、および ここ

これのためにPOJOクラスを作成することができますが、それをParcelableにするためにいくつかの追加のコードを追加する必要があります。実装を見てください。

public class Student implements Parcelable{
        private String id;
        private String name;
        private String grade;

        // Constructor
        public Student(String id, String name, String grade){
            this.id = id;
            this.name = name;
            this.grade = grade;
       }
       // Getter and setter methods
       .........
       .........

       // Parcelling part
       public Student(Parcel in){
           String[] data = new String[3];

           in.readStringArray(data);
           // the order needs to be the same as in writeToParcel() method
           this.id = data[0];
           this.name = data[1];
           this.grade = data[2];
       }

       @Оverride
       public int describeContents(){
           return 0;
       }

       @Override
       public void writeToParcel(Parcel dest, int flags) {
           dest.writeStringArray(new String[] {this.id,
                                               this.name,
                                               this.grade});
       }
       public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
           public Student createFromParcel(Parcel in) {
               return new Student(in); 
           }

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

このクラスを作成したら、このクラスのオブジェクトをこのようにIntentを通して簡単に渡すことができ、ターゲットアクティビティでこのオブジェクトを回復できます。

intent.putExtra("student", new Student("1","Mike","6"));

ここでは、生徒がバンドルからデータを展開するために必要な鍵です。

Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");

この例はString型のみを示しています。しかし、あなたはあなたが望むどんな種類のデータでもパーセルすることができます。やってみよう。

編集:別の Rukmal Dias が提案。

422
fiction

作成したクラスからParcelable Classを作成するためのWebサイトです。

http://www.parcelabler.com/

186
francisco_ssb

IntelliJ IDEA とAndroid Studioにはこのためのプラグインがあります。

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

Plugin demo

109
naXa

1. Android Parcelable code generatorをインポートする

enter image description here

2.クラスを作る

public class Sample {
    int id;
    String name;
}

3.メニューから生成> Parcelable

enter image description hereenter image description here

完了しました。

53
itiskj

どうやって?注釈付き。

POJOに特別な注釈を付けるだけで、残りはライブラリで行います。

警告!

Hrisey、Lombok、その他のコード生成ライブラリがAndroidの新しいビルドシステムと互換性があるかどうかはわかりません。それらはホットスワップコード(つまりjRebel、Instant Run)とうまく機能するかどうかはわかりません。

長所:

  • コード生成ライブラリは、定型的なソースコードからあなたを救います。
  • 注釈はあなたのクラスを美しくします。

短所:

  • 単純なクラスではうまくいきます。複雑なクラスを解析可能にするのは難しいかもしれません。
  • LombokとAspectJはうまくいっていません。 [詳細]
  • 私の警告を見なさい。

フリーズリー

警告!

HriseyにはJava 8に関する既知の問題があるため、今日ではAndroidの開発には使用できません。 を参照してください。#1シンボルエラーが見つかりません(JDK 8)

Hriseyは Lombok に基づいています。 Hrisey を使用して解析可能なクラス:

@hrisey.Parcelable
public final class POJOClass implements Android.os.Parcelable {
    /* Fields, accessors, default constructor */
}

これで、Parcelableインタフェースのメソッドを実装する必要はありません。 Hriseyは前処理段階で必要なコードをすべて生成します。

Gradleの依存関係におけるHrisey:

provided "pl.mg6.hrisey:hrisey:${hrisey.version}"

サポートされている型についてはこちら をご覧ください。 ArrayListはその中にあります。

IDE用のプラグイン(Hrisey xor Lombok *)をインストールして、その素晴らしい機能を使い始めましょう。

enter image description here
* HriseyプラグインとLombokプラグインを同時に有効にしないと、IDE起動中にエラーが発生します。


パーセラー

Parceler を使用して解析可能なクラス:

@Java.org.parceler.Parcel
public class POJOClass {
    /* Fields, accessors, default constructor */
}

生成されたコードを使用するには、生成されたクラスを直接参照するか、Parcelsユーティリティクラスを介して次のように参照します。

public static <T> Parcelable wrap(T input);

@Parcelを間接参照するには、Parcelsクラスの次のメソッドを呼び出すだけです。

public static <T> T unwrap(Parcelable input);

GradleのParcelerの依存関係:

compile "org.parceler:parceler-api:${parceler.version}"
provided "org.parceler:parceler:${parceler.version}"

サポートされている 属性タイプ については、 README を参照してください。


オートパーセル

AutoParcel は、Parcelable値の生成を可能にする AutoValue の拡張です。

implements Parcelable注釈付きモデルに@AutoValueを追加するだけです。

@AutoValue
abstract class POJOClass implements Parcelable {
    /* Note that the class is abstract */
    /* Abstract fields, abstract accessors */

    static POJOClass create(/*abstract fields*/) {
        return new AutoValue_POJOClass(/*abstract fields*/);
    }
}

Gradleビルドファイルの自動パーセル:

apply plugin: 'com.Android.application'
apply plugin: 'com.neenbedankt.Android-apt'

repositories {
    /*...*/
    maven {url "https://clojars.org/repo/"}
}

dependencies {
    apt "frankiesardo:auto-parcel:${autoparcel.version}"
}

PaperParcel

PaperParcel は、KotlinおよびJava用の型保証されたParcelable定型コードを自動的に生成する注釈プロセッサです。 PaperParcelは、Kotlin Data Classes、AutoValue Extensionを介したGoogleのAutoValue、または通常のJava Beanオブジェクトをサポートします。

docs からの使用例。
あなたのデータクラスに@PaperParcelで注釈を付け、PaperParcelableを実装し、そしてPaperParcelable.CreatorのJVM静的インスタンスを追加してください。

@PaperParcel
public final class Example extends PaperParcelable {
    public static final PaperParcelable.Creator<Example> CREATOR = new PaperParcelable.Creator<>(Example.class);

    private final int test;

    public Example(int test) {
        this.test = test;
    }

    public int getTest() {
        return test;
    }
}

Kotlinをご利用の方は、 Kotlinの使い方 をご覧ください。 AutoValueユーザーの場合は、 AutoValueの使用法 を参照してください。


ParcelableGenerator

ParcelableGenerator(READMEは中国語で書かれているので理解できません。英語から中国語を話す開発者によるこの回答への貢献)大歓迎です

README からの使用例。

import com.baoyz.pg.Parcelable;

@Parcelable
public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

Android-apt プラグインは、Android Studioと組み合わせてアノテーションプロセッサを操作するのに役立ちます。

20
naXa

私はParcelableクラスを作成する最も簡単な方法を見つけました

enter image description here

7
Rjz Satvara

それは非常に簡単です、あなたがオブジェクトParcelableを作るためにあなたはAndroidスタジオのプラグインを使うことができます。

public class Persona implements Parcelable {
String nombre;
int edad;
Date fechaNacimiento;

public Persona(String nombre, int edad, Date fechaNacimiento) {
    this.nombre = nombre;
    this.edad = edad;
    this.fechaNacimiento = fechaNacimiento;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.nombre);
    dest.writeInt(this.edad);
    dest.writeLong(fechaNacimiento != null ? fechaNacimiento.getTime() : -1);
}

protected Persona(Parcel in) {
    this.nombre = in.readString();
    this.edad = in.readInt();
    long tmpFechaNacimiento = in.readLong();
    this.fechaNacimiento = tmpFechaNacimiento == -1 ? null : new Date(tmpFechaNacimiento);
}

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

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

Androidのparcableにはいくつかのユニークなことがあります。それらは以下の通りです:

  1. あなたは、区画にデータを置くのと同じ順序で区画を読む必要があります。
  2. 区画から読み取った後、区画は空になります。区画に3つのデータがある場合です。それから3回読んだ後小包は空になります。

例:クラスをParcebleにするには、Parcebleを実装する必要があります。パーカブルには2つの方法があります。

int describeContents();
void writeToParcel(Parcel var1, int var2);

Personクラスがあり、firstName、lastName、ageの3つのフィールドがあるとします。 Parcebleインターフェースを実装した後このインターフェースは以下の通りです:

import Android.os.Parcel;
import Android.os.Parcelable;
public class Person implements Parcelable{
    private String firstName;
    private String lastName;
    private int age;

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(firstName);
        parcel.writeString(lastName);
        parcel.writeInt(age);
    }

}

ここではwriteToParcelメソッドを順番にParcelにデータを書いたり追加しています。その後、区画からデータを読み取るための以下のコードを追加する必要があります。

protected Person(Parcel in) {
        firstName = in.readString();
        lastName = in.readString();
        age = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

ここでは、Personクラスが書き込み中に区画を取り、データを同じ順序で取得しています。

今意図している間にgetExtraputExtraコードは以下の通りです:

余分に入れてください

Person person=new Person();
                person.setFirstName("First");
                person.setLastName("Name");
                person.setAge(30);

                Intent intent = new Intent(getApplicationContext(), SECOND_ACTIVITY.class);
                intent.putExtra()
                startActivity(intent); 

追加取得:

Person person=getIntent().getParcelableExtra("person");

Full Personクラスは以下の通りです

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

public class Person implements Parcelable{
    private String firstName;
    private String lastName;
    private int age;



    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(firstName);
        parcel.writeString(lastName);
        parcel.writeInt(age);
    }

    protected Person(Parcel in) {
        firstName = in.readString();
        lastName = in.readString();
        age = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

}

Hope this will help you 
Thanks :)
0

これで、あなたは Parceler ライブラリを使って任意のカスタムクラスをparcelableに変換することができます。 POJOクラスに@ Parcelというアノテーションを付けるだけです。例えば.

    @Parcel
    public class Example {
    String name;
    int id;

    public Example() {}

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getName() { return name; }

    public int getId() { return id; }
}

exampleクラスのオブジェクトを作成してParcelをラップし、意図的にバンドルとして送信することができます。例えば

Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));

今すぐカスタムクラスオブジェクトを取得するために使用します

Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
0
Shubham Shukla