Özel nesnelerimi nasıl Parcelable yapabilirim?


338

Nesnelerimi Parcelable yapmaya çalışıyorum. Ancak, özel nesnelerim var ve bu ArrayListnesneler yaptığım diğer özel nesnelerin niteliklerine sahip.

Bunu yapmanın en iyi yolu ne olurdu?

Yanıtlar:


432

Burada , burada (kod burada alınır) ve burada bazı örnekler bulabilirsiniz .

Bunun için bir POJO sınıfı oluşturabilirsiniz, ancak bunu yapmak için bazı ekstra kodlar eklemeniz gerekir Parcelable. Uygulamaya bir göz atın.

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

Bu sınıfı oluşturduktan sonra, bu sınıftaki nesneleri bu şekilde kolayca geçirebilir Intentve bu nesneyi hedef etkinlikte kurtarabilirsiniz.

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

Burada, öğrenci verileri paketten ayırmak için ihtiyaç duyacağınız anahtardır.

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

Bu örnek yalnızca Stringtürleri gösterir . Ancak, istediğiniz her türlü veriyi paketleyebilirsiniz. Denemek.

EDIT: Rukmal Dias tarafından önerilen başka bir örnek .


@Rukmal Dias 10x. Aslında, cevabımı düzenlemeli ve bazı kod eklemeliyim, çünkü bu bağlantılar gelecekte bir gün aktif olmayacak.
kurgu

16
OP normal nesneler değil özel nesnelerin nasıl geçirileceğini soruyor. Herkes normal Dizeleri geçebilir. ÖZEL NESNE ile nasıl oluşturulacağını açıklar

Sadece LocalBroadcastManager kullanarak gönderirsem kodlama / kod çözme parçalarını gerçekten uygulamam gerekir mi? Parcelable'ı uygulamak ve ekstra olarak koymak yeterli mi?
JohnyTex

Dizeleri art arda yazmak yerine neden bir dize dizisi kullanıyorsunuz?
Quentin Roy

writeToParcelYöntemin içinde dize dizisi oluştururken üyelerin sırası önemli mi?
Prakhar Mohan Srivastava



56

1. İthalat Android Parcelable code generator

resim açıklamasını buraya girin

2. Bir sınıf oluşturun

public class Sample {
    int id;
    String name;
}

3. Oluştur> Menüden Parcelable

resim açıklamasını buraya girin resim açıklamasını buraya girin

Bitti.


7
Göz Depoları iletişim de bilinmeyenler için Bilmeyenler: File > Settings... > Pluginsve tıklayın Browse repositories...düğme.
DaedalusAlpha

Teşekkür ederim, çok yardımcı oldu!
Strahinja Ajvaz

21

Nasıl? Ek açıklamalarla.

Özel bir açıklama ile bir POJO'ya sadece açıklama eklersiniz ve gerisini kütüphane yapar.

Uyarı!

Hrisey, Lombok ve diğer kod oluşturma kitaplıklarının Android'in yeni derleme sistemi ile uyumlu olduğundan emin değilim. Çalışırken değiştirilebilir kodla (örn. JRebel, Anında Çalıştırma) iyi oynayabilir veya oynatamayabilir.

Artıları:

  • Kod oluşturma kitaplıkları sizi kaynak levhası kaynak kodundan kurtarır.
  • Ek açıklamalar sınıfınızı güzelleştirir.

Eksileri:

  • Basit sınıflar için iyi çalışır. Karmaşık bir sınıfı ayrıştırılabilir yapmak zor olabilir.
  • Lombok ve AspectJ birlikte iyi oynamıyorlar. [bilgilerini]
  • Uyarılarıma bakın.

Hrisey

Uyarı!

Hrisey'in Java 8 ile ilgili bilinen bir sorunu var ve bu nedenle günümüzde Android geliştirme için kullanılamıyor. Bkz. # 1 Sembol hataları bulunamıyor (JDK 8) .

Hrisey Lombok'a dayanıyor . Kullanarak Parcelable sınıf Hrisey :

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

Artık Parcelable arabiriminin herhangi bir yöntemini uygulamanıza gerek yoktur. Hrisey, önişleme aşamasında gerekli tüm kodları üretecektir.

Grad bağımlılıklarında Hrisey:

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

Desteklenen türler için buraya bakın . Bunlar ArrayListarasında.

IDE'niz için bir eklenti - Hrisey xor Lombok * - yükleyin ve şaşırtıcı özelliklerini kullanmaya başlayın!

resim açıklamasını buraya girin
* Hrisey ve Lombok eklentilerini birlikte etkinleştirmeyin, aksi takdirde IDE lansmanı sırasında bir hata alırsınız.


Parceler

Kullanarak Parcelable sınıf Parceler :

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

Oluşturulan kodu kullanmak için, oluşturulan sınıfa doğrudan veya Parcelsyardımcı sınıf aracılığıyla

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

Kayıttan ayrılmak için @Parcelaşağıdaki Parcelssınıf yöntemini çağırmanız yeterlidir

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

Gradle bağımlılıklarında parceler:

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

Desteklenen özellik türleri için README'ye bakın .


AutoParcel

AutoParcel , Parcelable değerleri oluşturulmasını sağlayan bir AutoValue uzantısıdır.

Sadece eklemek implements Parcelableiçin için @AutoValueaçıklamalı modeller:

@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 derleme dosyasında AutoParcel:

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 ve Java için otomatik olarak tip güvenliği Parcelable kazan plakası kodu üreten bir ek açıklama işlemcisidir. PaperParcel Kotlin Veri Sınıflarını, Google'ın bir AutoValue Uzantısı üzerinden AutoValue'unu veya sadece normal Java fasulye nesnelerini destekler.

Dokümanlardan kullanım örneği .
Veri sınıfınıza örneğin JVM statik örneğini ekleyin @PaperParcel, uygulayın PaperParcelableve ekleyin PaperParcelable.Creator:

@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 kullanıcıları için bkz. Kotlin Kullanımı ; Otomatik Değerleme kullanıcıları için, bkz. Otomatik Değerleme Kullanımı .


ParcelableGenerator

ParcelableGenerator (README Çince dilinde yazılmış ve anlamıyorum. İngilizce-Çince konuşan geliştiricilerin bu cevaba katkıları hoş karşılanmaktadır)

README kullanım örneği .

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 ile birlikte açıklama işlemciler çalışma konusunda eklenti asist.


7

Parcelable sınıfını oluşturmanın en basit yolunu buldum

resim açıklamasını buraya girin


1
küçük veriler için iyi çalışır, ancak karmaşık verileri alırsak bu işe yaramaz
Manohar Reddy

1

Çok kolaydır, Parcelables nesneleri yapmak için android stüdyosunda bir eklenti kullanabilirsiniz.

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

4
Ne eklenti demek istiyorsun?
naXa

0

Artık herhangi bir özel sınıfınızı parcelable biçiminde dönüştürmek için Parceler kütüphanesini kullanabilirsiniz . @Parcel ile POJO sınıfınıza not ekleyin . Örneğin

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

Örnek sınıfta bir nesne oluşturabilir ve Parseller arasında gezinebilir ve niyet yoluyla paket olarak gönderebilirsiniz. Örneğin

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

Şimdi Custom Class nesnesini almak için

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

0

Android parcable bazı benzersiz şeylere sahiptir. Bunlar feryat verilir:

  1. Parseli veriyi koyduğunuzla aynı sırada okumalısınız.
  2. Parsel parselden okuduktan sonra boşalır. Parselinizde 3 veri varsa. Sonra 3 kez okuduktan sonra parsel boş olacaktır.

Örnek: Bir sınıf Parceble yapmak için Parceble uygulanmalıdır. Percable'ın 2 yöntemi vardır:

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

Bir Person sınıfınız olduğunu ve bunun firstName, lastName ve age olmak üzere 3 alanı olduğunu varsayalım. Parceble arabirimini uyguladıktan sonra. bu arayüz aşağıda verilmiştir:

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

}

İşte writeToParcelbiz Parsel üzerinde bir sırayla veri yazma / ekleme yöntemi. Bundan sonra parselden veri okumak için feryat kodu eklemeliyiz:

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

Burada, Person sınıfı bir parsel alıyor ve yazma sırasında aynı sırada veri alıyor.

Şimdi niyet getExtrave putExtrakod sırasında feryat verilir:

Ekstra koyun :

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

Ekstra Alın:

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

Tam Kişi dersi aşağıdaki gibidir :

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

Android Studio'da eklentisiz Parcelable sınıfı oluşturma

sınıfınızda Parcelable uygular ve sonra imleci "Parcelable uygular" üzerine yerleştirin ve vurmak Alt+Enterve seçmek Add Parcelable implementation(resme bakın). bu kadar.

resim açıklamasını buraya girin


-3

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

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


3
ClassCastExceptionNesne uygulanmazsa bu yol açacaktır Serializable.
naXa

1
Bu kod snippet'i soruyu çözebilir, ancak bir açıklama dahil olmak , yayınınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu cevapladığınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceğini unutmayın. Lütfen kodunuzu açıklayıcı yorumlarla doldurmamaya çalışın, bu hem kodun hem de açıklamaların okunabilirliğini azaltır!
Ashish Ahuja
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.