在 Android 中 parcelable.readArrayList() 中使用 ClassLoader
Use of ClassLoader in parcelable.readArrayList() in Android
我有一个名为 FilterData 的 Class,它实现了 Parcelable。我有一个成员变量private ArrayList<String> listPropertyType;
在我的class、parcel.readArrayList(null)
中实现parcelable接口时,参数显示为ClassLoader object
。使用此成员变量,FilterData
class 将按预期工作。但是我想实现一个将 ClassLoader object
传递给 readArrayList()
方法的场景。
所以我从关于 public ArrayList readArrayList (ClassLoader loader)
的文档中收集到的内容是,如果 ArrayList
包含非原始 class ,我们必须使用 ClassLoader
.
在这个使用 ClassLoader 的场景中有什么用例以及如何使用它?我想在接下来的事情中使用 ClassLoader。添加了一个成员变量private ArrayList<RandomClass> listRandom; RandomClass randomClass;
来实现这个。
我的 FilterData
class 持有:
public FilterData(Parcel parcel)
{
listPropertyType=parcel.readArrayList(null);
listRandom=parcel.readArrayList(randomClass);
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeList(listPropertyType);
parcel.writeList(listRandom);
}
我的随机Class是:
public class RandomClass extends ClassLoader{
//this class is for testing classloader in ArrayList in parcelable .readArrayList()
String name;
int age;
public RandomClass(String name, int age) {
this.name = name;
this.age = age;
}
}
此实现无效。那么这个怎么用呢?
如果您从包裹中读取的数组列表是您创建的子类,而不是标准的 java 列表子类,或者如果它包含非基本类型,则需要传递 MyCustomList.class.getClassLoader().
你需要这样做,因为parcelables可以随时随地膨胀,所以代码必须知道加载它所需的ClassLoader。大多数时候你不需要它,因为你会在你自己的应用程序中打包东西,但这是一个很好的做法。
其实你说的是一个简单的列表ArrayList<String>
,所以你什么都不用做。如果它是 MyListSubclass<String>
、ArrayList<MyObject>
或可能包含其他子类对象的 ArrayList<HashMap<Object, Object>>
,则情况会有所不同。你明白了。
首先,如果我们想得到一个classParcelable
,我们可以使用一个网站www.parcelabler.com。它将生成 class 的语法。其次,如果我们想使用我们自己的 class 的 ArrayList。制作一个包含 ArrayList 的 Parcelable
class 是行不通的。我们还需要自定义 class Parcelable
。
如果一个需要parcelable的class包含一个成员变量ArrayList<String> list;
,则网站生成的class应该是:
public class MyParcelable implements Parcelable {
ArrayList<String> list;
public MyParcelable(ArrayList<String> list) {
this.list = list;
}
protected MyParcelable(Parcel in) {
if (in.readByte() == 0x01) {
list = new ArrayList<String>();
in.readList(list, String.class.getClassLoader());
} else {
list = null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (list == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(list);
}
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
@Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
@Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
如果 Class 包含我们这样制作的 class 的 ArrayList ArrayList<DummyClass> list;
,代码应该是:
public class MyComplexParcelable implements Parcelable {
ArrayList<DummyClass> list;
public MyComplexParcelable(ArrayList<DummyClass> list) {
this.list = list;
}
@Override
public String toString() {
return "MyComplexParcelable{" +
"list=" + list +
'}';
}
protected MyComplexParcelable(Parcel in) {
if (in.readByte() == 0x01) {
list = new ArrayList<DummyClass>();
in.readList(list, DummyClass.class.getClassLoader());
} else {
list = null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (list == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(list);
}
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<MyComplexParcelable> CREATOR = new Parcelable.Creator<MyComplexParcelable>() {
@Override
public MyComplexParcelable createFromParcel(Parcel in) {
return new MyComplexParcelable(in);
}
@Override
public MyComplexParcelable[] newArray(int size) {
return new MyComplexParcelable[size];
}
};
}
如果我们比较这两种情况,语法上没有区别。 class 都使用 in.readList(list, String.class.getClassLoader());
和 in.readList(list, DummyClass.class.getClassLoader());
都使用对应 classes.
的 ClassLoader 对象
但在后一种情况下,我们需要使 DummyClass
可打包。像这样:
public class DummyClass implements Parcelable {
int age;
String name;
public DummyClass(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "DummyClass{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
protected DummyClass(Parcel in) {
age = in.readInt();
name = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<DummyClass> CREATOR = new Parcelable.Creator<DummyClass>() {
@Override
public DummyClass createFromParcel(Parcel in) {
return new DummyClass(in);
}
@Override
public DummyClass[] newArray(int size) {
return new DummyClass[size];
}
};
}
我有一个名为 FilterData 的 Class,它实现了 Parcelable。我有一个成员变量private ArrayList<String> listPropertyType;
在我的class、parcel.readArrayList(null)
中实现parcelable接口时,参数显示为ClassLoader object
。使用此成员变量,FilterData
class 将按预期工作。但是我想实现一个将 ClassLoader object
传递给 readArrayList()
方法的场景。
所以我从关于 public ArrayList readArrayList (ClassLoader loader)
的文档中收集到的内容是,如果 ArrayList
包含非原始 class ,我们必须使用 ClassLoader
.
在这个使用 ClassLoader 的场景中有什么用例以及如何使用它?我想在接下来的事情中使用 ClassLoader。添加了一个成员变量private ArrayList<RandomClass> listRandom; RandomClass randomClass;
来实现这个。
我的 FilterData
class 持有:
public FilterData(Parcel parcel)
{
listPropertyType=parcel.readArrayList(null);
listRandom=parcel.readArrayList(randomClass);
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeList(listPropertyType);
parcel.writeList(listRandom);
}
我的随机Class是:
public class RandomClass extends ClassLoader{
//this class is for testing classloader in ArrayList in parcelable .readArrayList()
String name;
int age;
public RandomClass(String name, int age) {
this.name = name;
this.age = age;
}
}
此实现无效。那么这个怎么用呢?
如果您从包裹中读取的数组列表是您创建的子类,而不是标准的 java 列表子类,或者如果它包含非基本类型,则需要传递 MyCustomList.class.getClassLoader().
你需要这样做,因为parcelables可以随时随地膨胀,所以代码必须知道加载它所需的ClassLoader。大多数时候你不需要它,因为你会在你自己的应用程序中打包东西,但这是一个很好的做法。
其实你说的是一个简单的列表ArrayList<String>
,所以你什么都不用做。如果它是 MyListSubclass<String>
、ArrayList<MyObject>
或可能包含其他子类对象的 ArrayList<HashMap<Object, Object>>
,则情况会有所不同。你明白了。
首先,如果我们想得到一个classParcelable
,我们可以使用一个网站www.parcelabler.com。它将生成 class 的语法。其次,如果我们想使用我们自己的 class 的 ArrayList。制作一个包含 ArrayList 的 Parcelable
class 是行不通的。我们还需要自定义 class Parcelable
。
如果一个需要parcelable的class包含一个成员变量ArrayList<String> list;
,则网站生成的class应该是:
public class MyParcelable implements Parcelable {
ArrayList<String> list;
public MyParcelable(ArrayList<String> list) {
this.list = list;
}
protected MyParcelable(Parcel in) {
if (in.readByte() == 0x01) {
list = new ArrayList<String>();
in.readList(list, String.class.getClassLoader());
} else {
list = null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (list == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(list);
}
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
@Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
@Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
如果 Class 包含我们这样制作的 class 的 ArrayList ArrayList<DummyClass> list;
,代码应该是:
public class MyComplexParcelable implements Parcelable {
ArrayList<DummyClass> list;
public MyComplexParcelable(ArrayList<DummyClass> list) {
this.list = list;
}
@Override
public String toString() {
return "MyComplexParcelable{" +
"list=" + list +
'}';
}
protected MyComplexParcelable(Parcel in) {
if (in.readByte() == 0x01) {
list = new ArrayList<DummyClass>();
in.readList(list, DummyClass.class.getClassLoader());
} else {
list = null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (list == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(list);
}
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<MyComplexParcelable> CREATOR = new Parcelable.Creator<MyComplexParcelable>() {
@Override
public MyComplexParcelable createFromParcel(Parcel in) {
return new MyComplexParcelable(in);
}
@Override
public MyComplexParcelable[] newArray(int size) {
return new MyComplexParcelable[size];
}
};
}
如果我们比较这两种情况,语法上没有区别。 class 都使用 in.readList(list, String.class.getClassLoader());
和 in.readList(list, DummyClass.class.getClassLoader());
都使用对应 classes.
但在后一种情况下,我们需要使 DummyClass
可打包。像这样:
public class DummyClass implements Parcelable {
int age;
String name;
public DummyClass(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "DummyClass{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
protected DummyClass(Parcel in) {
age = in.readInt();
name = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<DummyClass> CREATOR = new Parcelable.Creator<DummyClass>() {
@Override
public DummyClass createFromParcel(Parcel in) {
return new DummyClass(in);
}
@Override
public DummyClass[] newArray(int size) {
return new DummyClass[size];
}
};
}