如何使我的自定义对象可打包?

我试着让我的对象可打包。但是,我有自定义对象,这些对象具有我所做的其他自定义对象的ArrayList属性。

最好的方法是什么?

267922 次浏览

你可以找到一些在这里这里(代码在这里)在这里的例子。

你可以为此创建一个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"));

在这里,student是将数据从包中解包所需要的键。

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

这个例子只显示了String类型。但是,你可以打包任何你想要的数据。试试吧。

编辑:另一个例子,由Rukmal迪亚斯建议。

< p >将: bundle.putSerializable("key",(Serializable) object); < / p > < p >得到: List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key")); < / p >

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

http://www.parcelabler.com/

如何?与注释。

您只需用一个特殊的注释注释POJO,库就会完成其余的工作。

警告!

我不确定Hrisey、Lombok和其他代码生成库是否与Android的新构建系统兼容。它们可能与热交换代码(如jRebel, Instant Run)很好地兼容,也可能不兼容。

优点:

  • 代码生成库将您从样板源代码中拯救出来。
  • 注释使你的类更漂亮。

缺点:

  • 它适用于简单的类。使一个复杂的类可打包可能是棘手的。
  • Lombok和AspectJ不能很好地配合使用。< a href = " https://groups.google.com/forum/ !topic/project-lombok/ZkLsTZVSgD4" rel="nofollow noreferrer">[details]
  • 请看我的警告。

一个位于

警告!

Hrisey在Java 8上有一个已知的问题,因此现在不能用于Android开发。 看到无法找到符号错误(JDK 8)。< / p >

Hrisey基于Lombok。Parcelable类使用一个位于:

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

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

Hrisey在Gradle依赖:

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

在这里看到的用于支持的类型。ArrayList就是其中之一。

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

< p > enter image description here < br > *不要同时启用Hrisey和Lombok插件,否则在IDE启动时会出现错误

包裹

Parcelable类使用包裹:

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

要使用生成的代码,您可以直接引用生成的类,或通过Parcels实用工具类using

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

自述中查找受支持的属性类型


AutoParcel

AutoParcel是一个支持Parcelable值生成的AutoValue扩展。

只需将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*/);
}
}

AutoParcel在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是一个注释处理器,它自动为Kotlin和Java生成类型安全的Parcelable样板代码。PaperParcel支持Kotlin数据类,谷歌的AutoValue通过AutoValue扩展,或者只是普通的Java bean对象。

文档的用法示例 用@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用户,请参见芬兰湾的科特林使用;对于AutoValue用户,请参见AutoValue用法


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结合使用注释处理器。

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

这些插件基于类中的字段生成Android Parcelable样板代码。

Plugin demo

这很简单,你可以在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];
}
};}

1. 进口Android Parcelable code generator

enter image description here

2. 创建类

public class Sample {
int id;
String name;
}

3.从菜单生成> Parcelable

enter image description here enter image description here < / p >

完成了。

现在你可以使用包裹库转换你的任何自定义类在parcelable。只要用@Parcel注释你的POJO类。 例如< / p >

    @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 bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));

现在要获得自定义类对象只需使用

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

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

enter image description here

Android parcable有一些独特之处。这些因素如下:

  1. 你必须读包裹作为相同的顺序,你把数据包裹。
  2. 从包裹中读取包裹后,包裹将被清空。如果您的包裹上有3个数据。然后在阅读3次后包裹将是空的。
< p >的例子: 要使一个类成为Parceble,它必须实现Parceble。perable有2个方法:

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

假设你有一个Person类,它有三个字段,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代码如下所示:

多放点:

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

完整的人类给出如下:

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类

在你的类中实现Parcelable,然后把光标放在“implements Parcelable”上,点击Alt+Enter并选择Add Parcelable implementation(见图片)。就是这样。

enter image description here

我尝试使用Parcellable,时间很短,所以使用Gson如下。也许它能帮助到少数人…

PersonData personData;
BusinessData businessData;

以上两个都是模型对象。我想把它从loginactivity。class传递给mainactivity。class。Parcellable无法使用大型模型,需要时间进行修改。

startActivity(
new Intent(LogInActivity.this, MainActivity.class)
.putExtra("businessData", new Gson().toJson(businessData))
.putExtra("personData", new Gson().toJson(personData))
);

在MainActivity.class中检索这些对象

BusinessData businessData = new Gson().fromJson(getIntent().getStringExtra("businessData"), BusinessData.class);
PresonData personData = new Gson().fromJson(getIntent().getStringExtra("personData"), PersonData.class);