使用 Parcelable 在活动之间传递高度嵌套 类
Using Parcelable to pass highly nested classes between Activities
假设我想在 Intent
中存储类型 MyObject
的自定义对象。这样做的方法是让 MyObject
实现 Parcelable
。如果 MyObject
的字段之一也是类型 Widget
的自定义对象,显而易见的事情是让 Widget
也实现 Parcelable
。
问题在于实施时涉及大量样板 Parcelable
。你可以通过不让 Widget
实现 Parcelable
来解决这个问题,而是只给它一个采用 Parcel
和方法 writeToParcel
的构造函数,如下所示:
public final class Widget {
private final int a;
private final String b;
Widget(Parcel in) {
a = in.readInt();
b = in.readString();
}
void writeToParcel(Parcel out) {
out.writeInt(a);
out.writeString(b);
}
}
然后您可以在 Parcelable
对象中有一个 Widget
字段,如下所示:
public class MyObject implements Parcelable {
private final int x;
private final Widget w;
MyObject(int x, Widget w) {
this.x = x;
this.w = w;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(x);
w.writeToParcel(out);
}
public static final Parcelable.Creator<MyObject> CREATOR
= new Parcelable.Creator<MyObject>() {
@Override
public MyObject createFromParcel(Parcel in) {
return new MyObject(in.readInt(), new Widget(in));
}
@Override
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
}
这是可以接受的方法吗?在一个项目中有许多自定义 类 可以写入和读取 Parcel
而无需它们实际实现 Parcelable
是否被认为是单一的 android?或者我正在使用 Parcelable
传递具有许多自定义类型字段的复杂对象(这些字段又具有许多自定义类型字段等)这一事实表明我不应该使用 Parcelable
首先?
在处理通过 Android 中的意图传递自定义对象时,建议使用 Parcelable
。没有 "easy" 解决方法。由于您只处理一个额外级别的自定义对象(小部件),我建议您也制作 Widget
Parcelable
。您还可以查看此 link 以了解为什么它比使用默认序列化更好。 https://coderwall.com/p/vfbing/passing-objects-between-activities-in-android
我愿意(并且确实)选择 Parceler:https://github.com/johncarl81/parceler
Parceler is a code generation library that generates the Android
Parcelable boilerplate source code. No longer do you have to implement
the Parcelable interface, the writeToParcel() or createFromParcel() or
the public static final CREATOR. You simply annotate a POJO with
@Parcel and Parceler does the rest.
真的好用
如果您的 classes 是 beans,最好的解决方案是公认的解决方案。如果没有,我发现您可以(稍微)通过创建抽象 classes ParcelablePlus
和 CreatorPlus
来减轻实现 Parcelable
的痛苦。
ParcelablePlus
:
abstract class ParcelablePlus implements Parcelable {
@Override
public final int describeContents() {
return 0;
}
}
CreatorPlus
:
abstract class CreatorPlus<T extends Parcelable> implements Parcelable.Creator<T> {
private final Class<T> clazz;
CreatorPlus(Class<T> clazz) {
this.clazz = clazz;
}
@Override
@SuppressWarnings("unchecked")
public final T[] newArray(int size) {
// Safe as long as T is not a generic type.
return (T[]) Array.newInstance(clazz, size);
}
}
然后 Widget
class 变成:
public final class Widget extends ParcelablePlus {
private final int a;
private final String b;
Widget(int a, String b) {
this.a = a;
this.b = b;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(a);
out.writeString(b);
}
public static final Creator<Widget> CREATOR = new CreatorPlus<Widget>(Widget.class) {
@Override
public Widget createFromParcel(Parcel in) {
return new Widget(in.readInt(), in.readString());
}
};
}
假设我想在 Intent
中存储类型 MyObject
的自定义对象。这样做的方法是让 MyObject
实现 Parcelable
。如果 MyObject
的字段之一也是类型 Widget
的自定义对象,显而易见的事情是让 Widget
也实现 Parcelable
。
问题在于实施时涉及大量样板 Parcelable
。你可以通过不让 Widget
实现 Parcelable
来解决这个问题,而是只给它一个采用 Parcel
和方法 writeToParcel
的构造函数,如下所示:
public final class Widget {
private final int a;
private final String b;
Widget(Parcel in) {
a = in.readInt();
b = in.readString();
}
void writeToParcel(Parcel out) {
out.writeInt(a);
out.writeString(b);
}
}
然后您可以在 Parcelable
对象中有一个 Widget
字段,如下所示:
public class MyObject implements Parcelable {
private final int x;
private final Widget w;
MyObject(int x, Widget w) {
this.x = x;
this.w = w;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(x);
w.writeToParcel(out);
}
public static final Parcelable.Creator<MyObject> CREATOR
= new Parcelable.Creator<MyObject>() {
@Override
public MyObject createFromParcel(Parcel in) {
return new MyObject(in.readInt(), new Widget(in));
}
@Override
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
}
这是可以接受的方法吗?在一个项目中有许多自定义 类 可以写入和读取 Parcel
而无需它们实际实现 Parcelable
是否被认为是单一的 android?或者我正在使用 Parcelable
传递具有许多自定义类型字段的复杂对象(这些字段又具有许多自定义类型字段等)这一事实表明我不应该使用 Parcelable
首先?
在处理通过 Android 中的意图传递自定义对象时,建议使用 Parcelable
。没有 "easy" 解决方法。由于您只处理一个额外级别的自定义对象(小部件),我建议您也制作 Widget
Parcelable
。您还可以查看此 link 以了解为什么它比使用默认序列化更好。 https://coderwall.com/p/vfbing/passing-objects-between-activities-in-android
我愿意(并且确实)选择 Parceler:https://github.com/johncarl81/parceler
Parceler is a code generation library that generates the Android Parcelable boilerplate source code. No longer do you have to implement the Parcelable interface, the writeToParcel() or createFromParcel() or the public static final CREATOR. You simply annotate a POJO with @Parcel and Parceler does the rest.
真的好用
如果您的 classes 是 beans,最好的解决方案是公认的解决方案。如果没有,我发现您可以(稍微)通过创建抽象 classes ParcelablePlus
和 CreatorPlus
来减轻实现 Parcelable
的痛苦。
ParcelablePlus
:
abstract class ParcelablePlus implements Parcelable {
@Override
public final int describeContents() {
return 0;
}
}
CreatorPlus
:
abstract class CreatorPlus<T extends Parcelable> implements Parcelable.Creator<T> {
private final Class<T> clazz;
CreatorPlus(Class<T> clazz) {
this.clazz = clazz;
}
@Override
@SuppressWarnings("unchecked")
public final T[] newArray(int size) {
// Safe as long as T is not a generic type.
return (T[]) Array.newInstance(clazz, size);
}
}
然后 Widget
class 变成:
public final class Widget extends ParcelablePlus {
private final int a;
private final String b;
Widget(int a, String b) {
this.a = a;
this.b = b;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(a);
out.writeString(b);
}
public static final Creator<Widget> CREATOR = new CreatorPlus<Widget>(Widget.class) {
@Override
public Widget createFromParcel(Parcel in) {
return new Widget(in.readInt(), in.readString());
}
};
}