Wie kann ich meine benutzerdefinierten Objekte paketierbar machen?


338

Ich versuche, meine Objekte paketfähig zu machen. Ich habe jedoch benutzerdefinierte Objekte und diese Objekte haben ArrayListAttribute anderer benutzerdefinierter Objekte, die ich erstellt habe.

Was wäre der beste Weg, dies zu tun?

Antworten:


431

Einige Beispiele hierfür finden Sie hier , hier (Code wird hier verwendet) und hier .

Sie können hierfür eine POJO-Klasse erstellen, müssen jedoch zusätzlichen Code hinzufügen, um dies zu erreichen Parcelable. Schauen Sie sich die Implementierung an.

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

Sobald Sie diese Klasse erstellt haben, können Sie Objekte dieser Klasse auf einfache Weise Intentwie folgt übergeben und dieses Objekt in der Zielaktivität wiederherstellen.

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

Hier ist der Schüler der Schlüssel, den Sie benötigen würden, um die Daten aus dem Bundle zu entfernen.

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

Dieses Beispiel zeigt nur StringTypen. Sie können jedoch jede Art von Daten paketieren, die Sie möchten. Versuch es.

EDIT: Ein weiteres Beispiel , vorgeschlagen von Rukmal Dias .


@ Rukmal Dias 10x. Tatsächlich muss ich meine Antwort bearbeiten und Code hinzufügen, da diese Links eines Tages in Zukunft nicht mehr aktiv sein werden.
Fiktion

16
OP fragt, wie benutzerdefinierte Objekte übergeben werden sollen, die keine regulären Zeichenfolgen sind. Jeder kann reguläre Strings bestehen. Könnten Sie erklären, wie man es mit CUSTOM OBJECT erstellt

Muss ich die Codierungs- / Decodierungsteile tatsächlich implementieren, wenn ich sie nur mit LocalBroadcastManager sende? Reicht es aus, Parcelable zu implementieren und als Extra zu setzen?
JohnyTex

Warum verwenden Sie ein String-Array, anstatt die Strings nur nacheinander zu schreiben?
Quentin Roy

Ist die Reihenfolge der Mitglieder beim Erstellen des String-Arrays innerhalb der writeToParcelMethode von Bedeutung?
Prakhar Mohan Srivastava



56

1. Importieren Android Parcelable code generator

Geben Sie hier die Bildbeschreibung ein

2. Erstellen Sie eine Klasse

public class Sample {
    int id;
    String name;
}

3. Generieren> Paketieren aus dem Menü

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Erledigt.


7
Für diejenigen, die nicht wissen, wo sich das Dialogfeld "Repositorys durchsuchen" befindet: File > Settings... > Pluginsund auf die Browse repositories...Schaltfläche klicken .
DaedalusAlpha

Danke, hat mir sehr geholfen!
Strahinja Ajvaz

21

Wie? Mit Anmerkungen.

Sie kommentieren einfach ein POJO mit einer speziellen Anmerkung und die Bibliothek erledigt den Rest.

Warnung!

Ich bin nicht sicher, ob Hrisey, Lombok und andere Codegenerierungsbibliotheken mit dem neuen Build-System von Android kompatibel sind. Sie können mit Hot-Swapping-Code (z. B. jRebel, Instant Run) gut spielen oder auch nicht.

Vorteile:

  • Codegenerierungsbibliotheken speichern Sie vor dem Quellcode des Boilerplates.
  • Anmerkungen machen Ihre Klasse schön.

Nachteile:

  • Es funktioniert gut für einfache Klassen. Es kann schwierig sein, ein komplexes Klassenpaket zu erstellen.
  • Lombok und AspectJ spielen nicht gut zusammen. [Einzelheiten]
  • Siehe meine Warnungen.

Hrisey

Warnung!

Hrisey hat ein bekanntes Problem mit Java 8 und kann daher heutzutage nicht für die Android-Entwicklung verwendet werden. Siehe Nr. 1. Symbolfehler können nicht gefunden werden (JDK 8) .

Hrisey basiert auf Lombok . Paketklasse mit Hrisey :

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

Jetzt müssen Sie keine Methoden der Parcelable-Schnittstelle implementieren. Hrisey generiert während der Vorverarbeitungsphase den gesamten erforderlichen Code.

Hrisey in Gradle-Abhängigkeiten:

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

Hier finden Sie unterstützte Typen. Das ArrayListist unter ihnen.

Installieren Sie ein Plugin - Hrisey xor Lombok * - für Ihre IDE und nutzen Sie die erstaunlichen Funktionen!

Geben Sie hier die Bildbeschreibung ein
* Aktivieren Sie die Hrisey- und Lombok-Plugins nicht zusammen, da sonst beim Start der IDE eine Fehlermeldung angezeigt wird.


Paketierer

Paketklasse mit Parceler :

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

Um den generierten Code zu verwenden, können Sie direkt oder über die ParcelsUtility-Klasse mit auf die generierte Klasse verweisen

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

Um die dereferenzieren zu können @Parcel, rufen Sie einfach die folgende ParcelsKlassenmethode auf

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

Parceler in Gradle-Abhängigkeiten:

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

Suchen Sie in README nach unterstützten Attributtypen .


AutoParcel

AutoParcel ist eine AutoValue- Erweiterung, die die Generierung von Paketwerten ermöglicht.

Fügen implements ParcelableSie einfach Ihren @AutoValuekommentierten Modellen hinzu:

@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 in Gradle-Build-Datei:

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 ist ein Annotationsprozessor, der automatisch typsicheren Parcelable Boilerplate-Code für Kotlin und Java generiert. PaperParcel unterstützt Kotlin-Datenklassen, Googles AutoValue über eine AutoValue-Erweiterung oder nur normale Java-Bean-Objekte.

Verwendungsbeispiel aus Dokumenten .
Anmerken Ihre Datenklasse mit @PaperParcel, implementieren PaperParcelable, und fügen Sie eine JVM statische Instanz von PaperParcelable.CreatorzB:

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

Informationen zu Kotlin-Benutzern finden Sie unter Kotlin-Verwendung . Informationen zu AutoValue-Benutzern finden Sie unter AutoValue-Verwendung .


ParcelableGenerator

ParcelableGenerator (README ist auf Chinesisch geschrieben und ich verstehe es nicht. Beiträge zu dieser Antwort von englisch-chinesisch sprechenden Entwicklern sind willkommen.)

Anwendungsbeispiel aus 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;
    }

}

Das android-apt Plugin unterstützt Sie bei der Arbeit mit Anmerkungsprozessoren in Kombination mit Android Studio.


7

Ich habe den einfachsten Weg gefunden, eine Paketklasse zu erstellen

Geben Sie hier die Bildbeschreibung ein


1
es funktioniert gut für kleine Daten, aber wenn wir komplexe Daten nehmen, wird dies nicht funktionieren
Manohar Reddy

1

Es ist sehr einfach, Sie können ein Plugin auf Android Studio verwenden, um Objekte Parcelables zu machen.

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
Welches Plugin meinst du?
NaXa

0

Jetzt können Sie die Parceler- Bibliothek verwenden, um Ihre benutzerdefinierte Klasse in Parcelable zu konvertieren. Kommentieren Sie einfach Ihre POJO-Klasse mit @Parcel . z.B

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

Sie können ein Objekt der Beispielklasse erstellen, Pakete umbrechen und durch Absicht als Bundle senden. z.B

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

Um nun ein benutzerdefiniertes Klassenobjekt zu erhalten, verwenden Sie einfach

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

0

Android Parcable hat einige einzigartige Dinge. Diese sind unten angegeben:

  1. Sie müssen Parcel in derselben Reihenfolge lesen, in der Sie Daten auf das Paket legen.
  2. Das Paket wird nach dem Lesen aus dem Paket leer. Das ist, wenn Sie 3 Daten auf Ihrem Paket haben. Nach dreimaligem Lesen ist das Paket dann leer.

Beispiel: Um eine Klasse Parceble zu erstellen, muss Parceble implementiert werden. Percable hat 2 Methoden:

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

Angenommen, Sie haben eine Personenklasse mit drei Feldern: Vorname, Nachname und Alter. Nach der Implementierung der Parceble-Schnittstelle. Diese Schnittstelle ist unten angegeben:

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

}

Hier writeToParcelschreiben / fügen wir Daten auf Paket in einer Bestellung hinzu. Danach müssen wir folgenden Code zum Lesen von Daten aus dem Paket hinzufügen:

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

Hier nimmt die Personenklasse ein Paket entgegen und erhält während des Schreibens Daten in derselben Reihenfolge.

Jetzt wird während der Absicht getExtraund des putExtraCodes unten angegeben:

Extra hinzufügen :

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

Holen Sie sich extra:

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

Die vollständige Personenklasse wird unten angegeben :

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

Erstellen Sie eine Paketklasse ohne Plugin in Android Studio

implementiert Parcelable in Ihrer Klasse und setzt dann den Cursor auf "implementiert Parcelable" und drückt Alt+Enterund wählt Add Parcelable implementation(siehe Bild). das ist es.

Geben Sie hier die Bildbeschreibung ein


-3

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

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


3
Dies führt dazu, ClassCastExceptiondass das Objekt nicht implementiert wird Serializable.
NaXa

1
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen. Dies verringert die Lesbarkeit sowohl des Codes als auch der Erklärungen!
Ashish Ahuja
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.