首页 文章

如何使我的自定义对象Parcelable?

提问于
浏览
315

我正在尝试让我的对象Parcelable . 但是,我有自定义对象,这些对象具有我所做的其他自定义对象的 ArrayList 属性 .

最好的方法是什么?

10 回答

  • 415

    您可以找到herehere (code is taken here)here的一些示例 .

    您可以为此创建一个POJO类,但是您需要添加一些额外的代码才能使其成为Parcelable . 看看实现 .

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

    创建此类后,您可以轻松地通过此类Intent传递此类的对象,并在目标活动中恢复此对象 .

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

    在这里,学生是您需要从捆绑中取消数据的密钥 .

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

    此示例仅显示String类型 . 但是,您可以包含任何类型的数据 . 试试看 .

    编辑:另一个example,由Rukmal Dias建议 .

  • 2

    这是一个从您创建的类创建Parcelable类的网站:

    http://www.parcelabler.com/

  • 105

    IntelliJ IDEA和Android Studio有这样的插件:

    这些插件根据类中的字段生成Android Parcelable样板代码 .

    Plugin demo

  • 19

    1.导入Android Parcelable代码生成器

    enter image description here

    2.创建一个类

    public class Sample {
        int id;
        String name;
    }
    

    3.从菜单中生成> Parcelable

    enter image description here

    enter image description here

    完成 .

  • 185

    怎么样?带注释 .

    您只需使用特殊注释注释POJO,其余的就是库 .

    警告!我不确定Hrisey,Lombok和其他代码生成库是否与Android的新构建系统兼容 . 它们可能会或可能不会与热交换代码(即jRebel,Instant Run)很好地配合使用 .

    优点:

    • 代码生成库使您免受样板源代码的影响 .

    • 注释使你的课堂变得美丽 .

    缺点:

    • 适用于简单的类 . 制作复杂的类可能是棘手的 .

    • 龙目岛和AspectJ不能很好地融合在一起 . [细节]

    • 看到我的警告 .


    Hrisey

    警告! Hrisey在Java 8中存在已知问题,因此现在不能用于Android开发 . 请参阅#1找不到符号错误(JDK 8) .

    Hrisey基于Lombok . 使用Hrisey的Parcelable类:

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

    现在您不需要实现Parcelable接口的任何方法 . Hrisey将在预处理阶段生成所有必需的代码 .

    Hrisey in Gradle依赖:

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

    See here表示支持的类型 . ArrayList 就是其中之一 .

    安装一个插件 - Hrisey xor Lombok * - 用于您的IDE并开始使用其惊人的功能!

    enter image description here

    *在启动IDE时出现错误't enable Hrisey and Lombok plugins together or you' ll .


    Parceler

    使用Parceler的Parcelable类:

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

    要使用生成的代码,可以直接引用生成的类,也可以使用 Parcels 实用程序类引用

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

    要取消引用 @Parcel ,只需调用 Parcels 类的以下方法即可

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

    Gradle依赖项中的Parceler:

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

    查看README以获取支持的attribute types .


    AutoParcel

    AutoParcel是一个AutoValue扩展,可以生成Parcelable值 .

    只需将 implements Parcelable 添加到 @AutoValue 注释模型中:

    @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构建文件中的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和Java生成类型安全的Parcelable样板代码 . PaperParcel通过AutoValue扩展支持Kotlin数据类,Google的AutoValue,或者只支持常规的Java bean对象 .

    docs中的用法示例 .
    使用 @PaperParcel 注释您的数据类,实现 PaperParcelable ,并添加 PaperParcelable.Creator 的JVM静态实例,例如:

    @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用户,请参阅Kotlin Usage;对于AutoValue用户,请参阅AutoValue Usage .


    ParcelableGenerator

    ParcelableGenerator(README是用中文写的,我不明白 . 欢迎来自英语和汉语的开发人员给出这个答案的贡献)

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

    android-apt插件有助于将注释处理器与Android Studio结合使用 .

  • 50

    我找到了创建 Parcelable class 的最简单方法

    enter image description here

  • 0

    这很容易,你可以在android studio上使用插件来制作对象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];
        }
    };}
    
  • -3

    现在,您可以使用Parceler库转换parcelable中的任何自定义类 . 只需使用 @Parcel 注释您的POJO类 . 例如

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

    您可以创建Example类的对象并通过Parcel进行换行并通过intent发送为bundle . 例如

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

    现在只需使用Custom Class对象

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

    Android parcable有一些独特的东西 . 这些是下面给出的:

    • 您必须将Parcel读取为将数据放入parcel的相同顺序 .

    • 从包裹中读取后,包裹将清空 . 也就是说,如果您的包裹上有3个数据 . 然后在阅读3次后,包裹将为空 .

    示例:要创建Parceble类,必须实现Parceble . Percable有2种方法:

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

    假设您有一个Person类,它有3个字段,firstName,lastName和age . 实现Parceble接口后 . 这个界面如下:

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

    这里 writeToParcel 方法我们正在按顺序在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];
            }
        };
    

    在这里,Person类正在处理一个包裹并在写入期间以相同的顺序获取数据 .

    现在在意图 getExtraputExtra 代码下面给出:

    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

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

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

相关问题