Bagaimana saya bisa membuat objek khusus saya Parcelable?

338

Saya mencoba membuat benda saya Parcelable. Namun, saya memiliki objek khusus dan objek tersebut memiliki ArrayListatribut objek khusus lain yang telah saya buat.

apa jalan terbaik melakukan ini?

Jean Jimenez
sumber

Jawaban:

432

Anda dapat menemukan beberapa contohnya di sini , di sini (kode diambil di sini) , dan di sini .

Anda dapat membuat kelas POJO untuk ini, tetapi Anda perlu menambahkan beberapa kode tambahan untuk membuatnya Parcelable . Lihatlah implementasinya.

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];
           }
       };
   }

Setelah Anda membuat kelas ini, Anda dapat dengan mudah melewatkan objek kelas ini melalui Intentseperti ini, dan memulihkan objek ini di aktivitas target.

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

Di sini, siswa adalah kunci yang Anda perlukan untuk menghapus data dari bundel.

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

Contoh ini hanya menunjukkan String tipe. Tapi, Anda bisa membagi data apa pun yang Anda inginkan. Cobalah.

EDIT: Contoh lain , disarankan oleh Rukmal Dias .

fiksi
sumber
@Rukmal Dias 10x. Bahkan, saya harus mengedit jawaban saya dan menambahkan beberapa kode, karena tautan ini tidak lagi aktif di masa mendatang.
fiksi
16
OP bertanya bagaimana cara melewatkan objek khusus bukan string biasa. Siapa pun dapat melewati String biasa. Bisakah Anda menjelaskan BAGAIMANA membuatnya dengan CUSTOM OBJECT
Apakah saya harus benar-benar mengimplementasikan bagian-bagian penyandian / pengodean ulang jika saya hanya mengirimnya menggunakan LocalBroadcastManager? Apakah itu cukup untuk mengimplementasikan Parcelable dan dimasukkan sebagai tambahan?
JohnyTex
Mengapa Anda menggunakan larik string alih-alih hanya menulis string secara berurutan?
Quentin Roy
Apakah urutan anggota saat membuat array string di dalam writeToParcelmetode penting?
Prakhar Mohan Srivastava
193

Berikut adalah situs web untuk membuat Kelas Parcelable dari kelas buatan Anda:

http://www.parcelabler.com/

francisco_ssb
sumber
56

1. Impor Android Parcelable code generator

masukkan deskripsi gambar di sini

2. Buat kelas

public class Sample {
    int id;
    String name;
}

3. Hasilkan> Parcelable dari menu

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Selesai

kenju
sumber
7
Bagi mereka yang tidak tahu di mana dialog Browse Repositori berada di: File > Settings... > Pluginsdan klik Browse repositories...tombol.
DaedalusAlpha
Terima kasih, banyak membantu!
Strahinja Ajvaz
21

Bagaimana? Dengan anotasi.

Anda cukup membubuhi keterangan POJO dengan anotasi khusus dan perpustakaan mengerjakan sisanya.

Peringatan!

Saya tidak yakin bahwa Hrisey, Lombok, dan perpustakaan pembuat kode lainnya kompatibel dengan sistem build baru Android. Mereka mungkin atau mungkin tidak bermain dengan baik dengan kode swapping panas (yaitu jRebel, Instant Run).

Pro:

  • Pustaka pembuatan kode menyelamatkan Anda dari kode sumber boilerplate.
  • Anotasi membuat kelas Anda cantik.

Cons:

  • Ini bekerja dengan baik untuk kelas sederhana. Membuat parcelable kelas yang kompleks mungkin sulit.
  • Lombok dan AspectJ tidak bermain bersama dengan baik. [detail]
  • Lihat peringatan saya.

Hrisey

Peringatan!

Hrisey memiliki masalah yang diketahui dengan Java 8 dan karenanya tidak dapat digunakan untuk pengembangan Android saat ini. Lihat # 1 Tidak dapat menemukan kesalahan simbol (JDK 8) .

Hrisey berbasis di Lombok . Kelas parcelable menggunakan Hrisey :

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

Sekarang Anda tidak perlu mengimplementasikan metode antarmuka Parcelable. Hrisey akan menghasilkan semua kode yang diperlukan selama fase preprocessing.

Hrisey dalam dependensi Gradle:

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

Lihat di sini untuk jenis yang didukung. ItuArrayList antara mereka.

Instal sebuah plugin - Hrisey xor Lombok * - untuk IDE Anda dan mulai gunakan fitur-fiturnya yang menakjubkan!

masukkan deskripsi gambar di sini
* Jangan aktifkan plugin Hrisey dan Lombok bersama-sama atau Anda akan mendapatkan kesalahan saat peluncuran IDE.


Parceler

Kelas parcelable menggunakan Parceler :

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

Untuk menggunakan kode yang dihasilkan, Anda dapat mereferensikan kelas yang dihasilkan secara langsung, atau melalui Parcelskelas utilitas menggunakan

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

Untuk referensi @Parcel, panggil metode berikut Parcelskelas

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

Parceler dalam dependensi Gradle:

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

Lihat di README untuk tipe atribut yang didukung .


Paket Otomatis

AutoParcel adalah AutoValue ekstensi yang memungkinkan nilai-nilai Parcelable generasi.

Cukup tambahkan implements Parcelableke @AutoValuemodel beranotasi Anda :

@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*/);
    }
}

AutoParcel dalam file build 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 adalah prosesor anotasi yang secara otomatis menghasilkan kode boilerplate Parcelable aman untuk Kotlin dan Java. PaperParcel mendukung Kelas Data Kotlin, AutoValue Google melalui Ekstensi AutoValue, atau hanya objek kacang Java biasa.

Contoh penggunaan dari dokumen .
Beri anotasi kelas data Anda dengan @PaperParcel, terapkan PaperParcelable, dan tambahkan instance statis JVM dari PaperParcelable.Creatormis:

@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;
    }
}

Untuk pengguna Kotlin, lihat Penggunaan Kotlin ; Untuk pengguna AutoValue, lihat Penggunaan AutoValue .


Generalener Parcelable

Generalener Parcelable (README ditulis dalam bahasa Cina dan saya tidak memahaminya. Kontribusi untuk jawaban ini dari pengembang berbahasa Inggris-Cina dipersilakan)

Contoh penggunaan dari 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;
    }

}

The android-apt assist Plugin dalam bekerja dengan prosesor penjelasan dalam kombinasi dengan Android Studio.

NaXa
sumber
7

Saya telah menemukan cara paling sederhana untuk membuat kelas Parcelable

masukkan deskripsi gambar di sini

Rjz Satvara
sumber
1
ini bekerja dengan baik untuk data kecil, tetapi jika kita mengambil data yang kompleks ini tidak akan berfungsi
Manohar Reddy
1

Caranya sangat mudah, Anda bisa menggunakan plugin di android studio untuk membuat objek Parcelables.

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];
    }
};}
Aplikasi-Perangkat Lunak Pabrik
sumber
4
Apa maksud plugin Anda?
naXa
0

Sekarang Anda dapat menggunakan pustaka Parceler untuk mengonversi kelas kustom apa pun Anda dalam parcelable. Beri catatan pada kelas POJO Anda dengan @Parcel . misalnya

    @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; }
}

Anda dapat membuat objek kelas Contoh dan membungkus Paket dan mengirim sebagai bundel melalui niat. misalnya

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

Sekarang untuk mendapatkan objek Kelas Kustom, gunakan saja

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

Android parcable memiliki beberapa hal unik. Itu diberikan di bawah ini:

  1. Anda harus membaca Parcel sebagai urutan yang sama tempat Anda meletakkan data pada parcel.
  2. Parcel akan kosong setelah dibaca dari parcel. Itu jika Anda memiliki 3 data pada paket Anda. Kemudian setelah dibaca 3 kali parcel akan kosong.

Contoh: Untuk membuat kelas Parceble itu harus mengimplementasikan Parceble. Percable memiliki 2 metode:

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

Misalkan Anda memiliki kelas Person dan memiliki 3 bidang, firstName, lastName dan umur. Setelah mengimplementasikan antarmuka Parceble. antarmuka ini diberikan di bawah ini:

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);
    }

}

Di sini writeToParcelmetode kita menulis / menambahkan data pada Parcel dalam suatu pesanan. Setelah ini kita harus menambahkan kode di bawah ini untuk membaca data dari paket:

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];
        }
    };

Di sini, kelas Person mengambil paket dan mendapatkan data dalam urutan yang sama selama penulisan.

Sekarang selama niat getExtradan putExtrakode diberikan di bawah ini:

Masukkan Ekstra :

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); 

Dapatkan Ekstra:

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

Kelas Orang Penuh diberikan di bawah ini :

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 :)
Md. Sajedul Karim
sumber
0

Buat kelas Parcelable tanpa plugin di Android Studio

mengimplementasikan Parcelable di kelas Anda dan kemudian meletakkan kursor pada "mengimplementasikan Parcelable" dan tekan Alt+Enterdan pilih Add Parcelable implementation(lihat gambar). itu dia.

masukkan deskripsi gambar di sini

Nagvadiya Vishal
sumber
-3

Untuk menempatkan: bundle.putSerializable("key",(Serializable) object);

Mendapatkan: List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));

Macário
sumber
3
Ini akan menyebabkan ClassCastExceptionjika objek tidak diimplementasikan Serializable.
naXa
1
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Tolong juga cobalah untuk tidak membuat kerumunan kode Anda dengan komentar penjelasan, ini mengurangi keterbacaan kode dan penjelasan!
Ashish Ahuja