How can I make my custom objects Parcelable?

后端 未结 11 2499
旧巷少年郎
旧巷少年郎 2020-11-21 07:40

I\'m trying to make my objects Parcelable. However, I have custom objects and those objects have ArrayList attributes of other custom objects I have made.

相关标签:
11条回答
  • 2020-11-21 07:53

    Here is a website to create a Parcelable Class from your created class:

    http://www.parcelabler.com/

    0 讨论(0)
  • 2020-11-21 07:58

    IntelliJ IDEA and Android Studio have plugins for this:

    • ★ Android Parcelable code generator (Apache License 2.0)
    • Auto Parcel (The MIT License)
    • SerializableParcelable Generator (The MIT License)
    • Parcelable Code Generator (for Kotlin) (Apache License 2.0)

    These plugins generate Android Parcelable boilerplate code based on fields in the class.

    0 讨论(0)
  • 2020-11-21 07:58

    Android parcable has some unique things. Those are given bellow:

    1. You have to read Parcel as the same order where you put data on parcel.
    2. Parcel will empty after read from parcel. That is if you have 3 data on your parcel. Then after read 3 times parcel will be empty.

    Example: To make a class Parceble it must be implement Parceble. Percable has 2 method:

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

    Suppose you have a Person class and it has 3 field, firstName,lastName and age. After implementing Parceble interface. this interface is given bellow:

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

    Here writeToParcel method we are writing/adding data on Parcel in an order. After this we have to add bellow code for reading data from 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];
            }
        };
    

    Here, Person class is taking a parcel and getting data in same an order during writing.

    Now during intent getExtra and putExtra code is given bellow:

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

    Get Extra:

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

    Full Person class is given bellow:

    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 讨论(0)
  • 2020-11-21 08:00

    You can find some examples of this here, here (code is taken here), and here.

    You can create a POJO class for this, but you need to add some extra code to make it Parcelable. Have a look at the implementation.

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

    Once you have created this class, you can easily pass objects of this class through the Intent like this, and recover this object in the target activity.

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

    Here, the student is the key which you would require to unparcel the data from the bundle.

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

    This example shows only String types. But, you can parcel any kind of data you want. Try it out.

    EDIT: Another example, suggested by Rukmal Dias.

    0 讨论(0)
  • 2020-11-21 08:00

    Create Parcelable class without plugin in Android Studio

    implements Parcelable in your class and then put cursor on "implements Parcelable" and hit Alt+Enter and select Add Parcelable implementation (see image). that's it.

    0 讨论(0)
  • 2020-11-21 08:11

    How? With annotations.

    You simply annotate a POJO with a special annotation and library does the rest.

    Warning!

    I'm not sure that Hrisey, Lombok, and other code generation libraries are compatible with Android's new build system. They may or may not play nicely with hot swapping code (i.e. jRebel, Instant Run).

    Pros:

    • Code generation libraries save you from the boilerplate source code.
    • Annotations make your class beautiful.

    Cons:

    • It works well for simple classes. Making a complex class parcelable may be tricky.
    • Lombok and AspectJ don't play well together. [details]
    • See my warnings.

    Hrisey

    Warning!

    Hrisey has a known issue with Java 8 and therefore cannot be used for Android development nowadays. See #1 Cannot find symbol errors (JDK 8).

    Hrisey is based on Lombok. Parcelable class using Hrisey:

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

    Now you don't need to implement any methods of Parcelable interface. Hrisey will generate all required code during preprocessing phase.

    Hrisey in Gradle dependencies:

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

    See here for supported types. The ArrayList is among them.

    Install a plugin - Hrisey xor Lombok* - for your IDE and start using its amazing features!


    * Don't enable Hrisey and Lombok plugins together or you'll get an error during IDE launch.


    Parceler

    Parcelable class using Parceler:

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

    To use the generated code, you may reference the generated class directly, or via the Parcels utility class using

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

    To dereference the @Parcel, just call the following method of Parcels class

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

    Parceler in Gradle dependencies:

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

    Look in README for supported attribute types.


    AutoParcel

    AutoParcel is an AutoValue extension that enables Parcelable values generation.

    Just add implements Parcelable to your @AutoValue annotated models:

    @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 file:

    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 is an annotation processor that automatically generates type-safe Parcelable boilerplate code for Kotlin and Java. PaperParcel supports Kotlin Data Classes, Google's AutoValue via an AutoValue Extension, or just regular Java bean objects.

    Usage example from docs.
    Annotate your data class with @PaperParcel, implement PaperParcelable, and add a JVM static instance of PaperParcelable.Creator e.g.:

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

    For Kotlin users, see Kotlin Usage; For AutoValue users, see AutoValue Usage.


    ParcelableGenerator

    ParcelableGenerator (README is written in Chinese and I don't understand it. Contributions to this answer from english-chinese speaking developers are welcome)

    Usage example from 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 plugin assists in working with annotation processors in combination with Android Studio.

    0 讨论(0)
提交回复
热议问题