我正在尝试使我的对象可打包。但是,我有自定义对象,这些对象具有ArrayList
我制作的其他自定义对象的属性。
最好的方法是什么?
您可以在此处、此处(此处获取代码)和此处找到一些示例。
您可以为此创建一个 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
like this传递这个类的对象,并在目标activity中恢复这个对象。
intent.putExtra("student", new Student("1","Mike","6"));
在这里,学生是您从捆绑包中解包数据所需的密钥。
Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");
此示例仅显示String
类型。但是,您可以打包任何类型的数据。试试看。
编辑:另一个例子,由Rukmal Dias建议。
这是一个从您创建的类创建 Parcelable 类的网站:
IntelliJ IDEA和 Android Studio 对此有插件:
这些插件基于类中的字段生成 Android Parcelable样板代码。
您只需使用特殊注释对 POJO 进行注释,其余的由库完成。
警告!
我不确定 Hrisey、Lombok 和其他代码生成库是否与 Android 的新构建系统兼容。他们可能会也可能不会很好地使用热交换代码(即 jRebel,Instant Run)。
优点:
缺点:
警告!
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 将在预处理阶段生成所有必需的代码。
Gradle 依赖项中的 Hrisey:
provided "pl.mg6.hrisey:hrisey:${hrisey.version}"
有关支持的类型,请参见此处。ArrayList
是其中之一。
为您的 IDE 安装一个插件 - Hrisey xor Lombok* - 并开始使用其惊人的功能!
* 不要同时启用 Hrisey 和 Lombok 插件,否则在 IDE 启动期间会出现错误。
@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}"
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是一个注解处理器,可自动为 Kotlin 和 Java 生成类型安全的 Parcelable 样板代码。PaperParcel 通过 AutoValue 扩展支持 Kotlin 数据类、Google 的 AutoValue,或者只是普通的 Java bean 对象。
来自docs的用法示例。
用 注释您的数据类@PaperParcel
,实现PaperParcelable
并添加一个 JVM 静态实例,PaperParcelable.Creator
例如:
@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 用法;对于 AutoValue 用户,请参阅AutoValue 用法。
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 使用注释处理器。
这很简单,你可以使用 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];
}
};}
Android parcable 有一些独特的东西。这些在下面给出:
示例:要创建一个 Parceble 类,它必须实现 Parceble。Percable 有两种方法:
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 类在写入过程中以相同的顺序接收包裹并获取数据。
现在在意图getExtra
和putExtra
代码如下:
放入额外的:
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 :)
现在您可以使用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 类的对象并通过 Parcels 包装并通过意图作为捆绑发送。例如
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
现在要获取自定义类对象,只需使用
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
放在:
bundle.putSerializable("key",(Serializable) object);
要得到:
List<Object> obj = (List<Object>)((Serializable)bundle.getSerializable("key"));