Come posso rendere i miei oggetti personalizzati Parcelable?


338

Sto cercando di rendere i miei oggetti Parcelable. Tuttavia, ho oggetti personalizzati e quegli oggetti hanno ArrayListattributi di altri oggetti personalizzati che ho creato.

Quale sarebbe il modo migliore per farlo?

Risposte:


432

Puoi trovare alcuni esempi di questo qui , qui (il codice è preso qui) e qui .

È possibile creare una classe POJO per questo, ma è necessario aggiungere un codice aggiuntivo per farlo Parcelable. Dai un'occhiata all'implementazione.

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

Dopo aver creato questa classe, è possibile passare facilmente oggetti di questa classe in Intentquesto modo e recuperare questo oggetto nell'attività di destinazione.

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

Qui, lo studente è la chiave di cui avresti bisogno per separare i dati dal pacchetto.

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

Questo esempio mostra solo i Stringtipi. Ma puoi spedire i pacchi a qualunque tipo di dato tu voglia. Provalo.

EDIT: Un altro esempio , suggerito da Rukmal Dias .


@Rukmal Dias 10x. In effetti, devo modificare la mia risposta e aggiungere un po 'di codice, perché questi collegamenti non saranno più attivi un giorno in futuro.
fiction

16
OP che chiede come passare oggetti personalizzati non stringa normale. Chiunque può passare stringhe regolari. Potresti spiegare come crearlo con CUSTOM OBJECT

Devo implementare effettivamente le parti di codifica / decodifica se le invio solo tramite LocalBroadcastManager? È sufficiente implementare Parcelable e metterlo come extra?
JohnyTex,

Perché usi un array di stringhe invece di scrivere le stringhe successivamente?
Quentin Roy,

È importante l'ordine dei membri durante la creazione della matrice di stringhe all'interno del writeToParcelmetodo?
Prakhar Mohan Srivastava,



56

1. Importazione Android Parcelable code generator

inserisci qui la descrizione dell'immagine

2. Crea una classe

public class Sample {
    int id;
    String name;
}

3. Genera> Parcelable dal menu

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Fatto.


7
Per coloro che non sanno dove si trova la finestra di dialogo Sfoglia repository: File > Settings... > Pluginse fare clic sul Browse repositories...pulsante.
Dedalo,

Grazie, aiutato molto!
Strahinja Ajvaz,

21

Come? Con annotazioni.

È sufficiente annotare un POJO con un'annotazione speciale e la libreria fa il resto.

Avvertimento!

Non sono sicuro che Hrisey, Lombok e altre librerie di generazione di codice siano compatibili con il nuovo sistema di generazione di Android. Possono o meno giocare bene con il codice hot swap (es. JRebel, Instant Run).

Professionisti:

  • Le librerie di generazione del codice ti salvano dal codice sorgente del bollettino.
  • Le annotazioni rendono bella la tua classe.

Contro:

  • Funziona bene per lezioni semplici. Rendere un pacchetto di classi complesse può essere complicato.
  • Lombok e AspectJ non giocano bene insieme. [dettagli]
  • Vedi i miei avvertimenti.

Hrísey

Avvertimento!

Hrisey ha un problema noto con Java 8 e pertanto non può essere utilizzato per lo sviluppo di Android al giorno d'oggi. Vedi # 1 Impossibile trovare gli errori dei simboli (JDK 8) .

Hrisey è basato su Lombok . Classe parcelable usando Hrisey :

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

Ora non è necessario implementare alcun metodo di interfaccia parcelable. Hrisey genererà tutto il codice richiesto durante la fase di preelaborazione.

Dipendenze di Hrisey in Gradle:

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

Vedi qui per i tipi supportati. Il ArrayListè tra questi.

Installa un plugin - Hrisey xor Lombok * - per il tuo IDE e inizia a utilizzare le sue incredibili funzionalità!

inserisci qui la descrizione dell'immagine
* Non abilitare i plugin Hrisey e Lombok insieme o otterrai un errore durante il lancio di IDE.


Parceler

Classe parcelable usando Parceler :

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

Per utilizzare il codice generato, è possibile fare riferimento direttamente alla classe generata o tramite la Parcelsclasse di utilità utilizzando

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

Per determinare il @Parcel, basta chiamare il seguente metodo di Parcelsclasse

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

Pacchi in dipendenze Gradle:

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

Cerca in README i tipi di attributi supportati .


AutoParcel

AutoParcel è un'estensione AutoValue che consente la generazione di valori parcelabili.

Aggiungi implements Parcelableai tuoi @AutoValuemodelli annotati:

@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 nel file di 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 è un processore di annotazione che genera automaticamente il codice di targa caldaia parcelable sicuro per Kotlin e Java. PaperParcel supporta le classi di dati Kotlin, AutoValue di Google tramite un'estensione AutoValue o solo normali oggetti bean Java.

Esempio di utilizzo da documenti .
Annota la tua classe di dati con @PaperParcel, implementa PaperParcelablee aggiungi un'istanza statica JVM, PaperParcelable.Creatorad esempio:

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

Per gli utenti di Kotlin, vedere Utilizzo di Kotlin ; Per gli utenti di AutoValue, vedere Uso di AutoValue .


ParcelableGenerator

ParcelableGenerator (README è scritto in cinese e non lo capisco. I contributi a questa risposta da parte degli sviluppatori di lingua inglese-cinese sono i benvenuti)

Esempio di utilizzo da 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;
    }

}

Il plug -in android-apt aiuta a lavorare con processori di annotazioni in combinazione con Android Studio.


7

Ho trovato il modo più semplice per creare una classe parcelable

inserisci qui la descrizione dell'immagine


1
funziona bene per piccoli dati, ma se prendiamo dati complessi questo non funzionerà
Manohar Reddy

1

È molto semplice, è possibile utilizzare un plug-in su Android Studio per creare oggetti 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];
    }
};}

4
Quale plugin vuoi dire?
naXa

0

Ora puoi usare la libreria Parceler per convertire qualsiasi classe personalizzata in parcelable. Basta annotare la tua classe POJO con @Parcel . per esempio

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

puoi creare un oggetto di classe Esempio e avvolgere Parcels e inviarlo come un bundle attraverso l'intento. per esempio

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

Ora per ottenere l'oggetto di classe personalizzata basta usare

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

0

Il parcable di Android ha alcune cose uniche. Quelli sono dati sotto:

  1. Devi leggere il pacco nello stesso ordine in cui hai inserito i dati sul pacco.
  2. Il pacco si svuota dopo aver letto dal pacco. Cioè se hai 3 dati sul tuo pacco. Quindi dopo aver letto 3 volte il pacco sarà vuoto.

Esempio: per rendere Parceble una classe, è necessario implementare Parceble. Percable ha 2 metodi:

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

Supponiamo di avere una classe Person e che abbia 3 campi, firstName, lastName ed età. Dopo aver implementato l'interfaccia Parceble. questa interfaccia è indicata sotto:

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

}

Qui writeToParcelmetodo stiamo scrivendo / aggiungendo dati su pacchi in un ordine. Dopodiché dobbiamo aggiungere il seguente codice per leggere i dati dal pacco:

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

Qui, la classe Person sta prendendo un pacco e sta ottenendo i dati nello stesso ordine durante la scrittura.

Ora durante l'intento getExtrae il putExtracodice è dato sotto:

Aggiungi extra :

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

Ottieni extra:

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

La classe Full Person è indicata sotto :

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

Crea classe parcelable senza plugin in Android Studio

implementa Parcelable nella tua classe, quindi posiziona il cursore su "implementa Parcelable" e premi Alt+Entere seleziona Add Parcelable implementation(vedi immagine). questo è tutto.

inserisci qui la descrizione dell'immagine


-3

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

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


3
Ciò comporterà ClassCastExceptionse l'oggetto non viene implementato Serializable.
naXa,

1
Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Cerca inoltre di non aggiungere il tuo codice a commenti esplicativi, ciò riduce la leggibilità sia del codice che delle spiegazioni!
Ashish Ahuja,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.