如何使我的自定义对象可拆分?

问题描述 投票:335回答:11

我正在尝试使我的对象可包裹。但是,我有自定义对象,这些对象具有我创建的其他自定义对象的ArrayList属性。

什么是最好的方法?

android parcelable
11个回答
431
投票

您可以找到此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建议。


0
投票

在Android Studio中创建不带插件的Parcelable类

在您的课堂上实现可打包的实现,然后将光标放在“可实现打包的实现”上,然后单击Alt+Enter并选择Add Parcelable implementation(参见图片)。就这样。


-3
投票

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

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


192
投票

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

http://www.parcelabler.com/


113
投票

[IntelliJ IDEA和Android Studio具有此插件:

1。导入Android Parcelable code generator

enter image description here

2。创建课程

public class Sample {
    int id;
    String name;
}

3。从菜单生成>可打包]

enter image description hereenter image description here

完成。

如何?带有注释。

您只需使用特殊注释对POJO进行注释,其余的工作就由库完成。

警告!

我不确定Hrisey,Lombok和其他代码生成库是否与Android的新构建系统兼容。它们在热插拔代码(即jRebel,Instant Run)中可能不能很好地配合使用。

优点:

  • 代码生成库使您免于样板源代码。
  • 注释使您的班级漂亮。
  • 缺点:

    • 它适用于简单的课程。使一个复杂的类可拆分可能是棘手的。
  • Lombok和AspectJ的配合不好。 [details]
  • 请参阅我的警告。

  • Hrisey

    警告!

    Hrisey在Java 8中存在一个已知问题,因此目前不能用于Android开发。参见#1 Cannot find symbol errors (JDK 8)

    Hrisey基于Lombok。使用Hrisey的可拆分类:

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

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

    Gradle依赖项中的Hrisey:

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

    See here用于支持的类型。 ArrayList在其中。

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

    enter image description here*不要同时启用Hrisey和Lombok插件,否则在IDE启动过程中会出错。


    包裹

    使用Parceler的可拆分类:

    @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依赖项中的包裹:

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

    README中查找受支持的attribute types


    自动包裹

    [AutoParcelAutoValue扩展名,启用了可分割的值生成。

    只需将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生成类型安全的可打包样板代码。 PaperParcel支持Kotlin数据类,通过AutoValue扩展的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中的使用示例。

    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结合使用。

    我已经找到创建Parcelable类

    的最简单方法

    enter image description here

    非常简单,您可以使用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];
        }
    };}
    

    现在您可以使用Parceler库来转换可打包的任何自定义类。只需使用@ 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类的对象并包装包裹,并通过intent捆绑发送。例如

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

    现在只需使用就可以获取自定义类对象

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

    Android parcable具有一些独特之处。那些都在下面:

    1. 您必须按照将数据放在包裹上的相同顺序读取包裹。
  • 从包裹中读取包裹后,包裹将为空。就是说您的地块上有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方法,我们正在按顺序在宗地上写入/添加数据。之后,我们必须添加以下代码以从包裹中读取数据:

    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代码中给出以下信息:

    放入额外内容

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

    获得额外奖励:

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

    Full Person类的名称如下] ::

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

    在Android Studio中创建不带插件的Parcelable类

    在您的课堂上实现可打包的实现,然后将光标放在“可实现打包的实现”上,然后单击Alt+Enter并选择Add Parcelable implementation(参见图片)。就这样。

    enter image description here

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

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


    56
    投票

    1。导入Android Parcelable code generator


    21
    投票

    如何?带有注释。


    7
    投票

    我已经找到创建Parcelable类


    1
    投票

    非常简单,您可以使用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];
        }
    };}
    

    0
    投票

    现在您可以使用Parceler库来转换可打包的任何自定义类。只需使用@ Parcel注释您的POJO类。例如


    0
    投票

    Android parcable具有一些独特之处。那些都在下面:

    1. 您必须按照将数据放在包裹上的相同顺序读取包裹。
    © www.soinside.com 2019 - 2024. All rights reserved.