从包中存储和检索自定义可序列化 class 的 ArrayList
Store and retrieve ArrayList of custom serializable class from bundle
我知道在 Whosebug 上有很多关于在 Bundle
s 中存储 ArrayList
s 的问题,但即使阅读了其中的许多问题和文档,我还是不明白我在下面描述的问题.我并不是在寻求解决这个特定编程问题的帮助,因为我有一个 "solution",而是想了解为什么我会收到错误以及为什么我的 "solution" 有效。
标准 PointF
class 是(不幸的)不可序列化的,这就是为什么我扩展 class 并(希望正确地)实现 [=20 序列化的代码=]如下:
class PointFSerializable extends PointF implements Serializable
{
public PointFSerializable(PointF pointF) {
super(pointF.x, pointF.y);
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeFloat(x);
out.writeFloat(y);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
float x = in.readFloat();
float y = in.readFloat();
set(x,y);
}
private void readObjectNoData() throws ObjectStreamException {
set(0f,0f);
}
}
现在我有一个嵌套的 ArrayList
这样的 PointFSerializable
对象,它是 serializable
因为 ArrayList
和 PointFSerializable
是可序列化的,我可以因此放入 Bundle bundle
如下:
ArrayList<ArrayList<PointFSerializable>> drawingSerializable = new
ArrayList<ArrayList<PointFSerializable>>();
//populate the nested ArrayList
for([...]) {
ArrayList<PointFSerializable> strokeSerializable = new ArrayList<PointFSerializable>();
for([...]) {
strokeSerializable.add(new PointFSerializable(...));
}
drawingSerializable.add(strokeSerializable);
}
//Put it into the Bundle
bundle.putSerializable("Drawing", drawingSerializable);
在另一个函数中,我后来通过 getSerializable()
从 Bundle bundle
中检索了嵌套的 ArrayList
并进行了如下转换:
ArrayList<ArrayList<PointFSerializable>> drawingSerializable = (ArrayList<ArrayList<PointFSerializable>>)bundle.getSerializable("Drawing");
到目前为止一切都按预期工作,但现在我想遍历 drawingSerializable
:
for(ArrayList<PointFSerializable> strokeSerializable : drawingSerializable) {
for(PointFSerializable pointFSerializable : strokeSerializable) { //<--
[...]
}
}
在标有 <--
的行中,我得到一个
java.lang.ClassCastException: android.graphics.PointF cannot be cast to com.cgogolin.myapp.PointFSerializable
这是我不明白的。
我本以为这个错误是 strokeSerializable
类型 ArrayList<PointF>
,但是,显然它不应该是,因为我将它定义为 ArrayList<PointFSerializable>
类型,如果它如果不是那种类型,那么我预计已经在外部 for 循环中得到一个错误。
现在,在内部 for 循环的主体中,我无论如何都想将 pointFSerializable
转换为 PointF
。因此,我可以用
替换有问题的行
for(PointF pointF : strokeSerializable) {
然后一切正常。但是为什么?
为什么,从 bundle.getSerializable("Drawing");
,我显然取回了一些我可以像 ArrayList<ArrayList<PointF>>
一样对待的东西(它甚至不是一个可序列化的对象!)但不像 ArrayList<ArrayList<PointFSerializable>>
,即使我将后一种类型的对象放入 Bundle?
PointF 是可打包的,这意味着您可以将标准 PointF 打包。如果 class 既可序列化又可打包,Android 将延迟写入和读取包裹。发生的事情是因为您没有覆盖分割方法,Android 将您的对象分割为标准 PointF。如果您需要能够在 class 之外序列化您的 class,请确保重写 Parcelable 接口中所需的方法。
我知道在 Whosebug 上有很多关于在 Bundle
s 中存储 ArrayList
s 的问题,但即使阅读了其中的许多问题和文档,我还是不明白我在下面描述的问题.我并不是在寻求解决这个特定编程问题的帮助,因为我有一个 "solution",而是想了解为什么我会收到错误以及为什么我的 "solution" 有效。
标准 PointF
class 是(不幸的)不可序列化的,这就是为什么我扩展 class 并(希望正确地)实现 [=20 序列化的代码=]如下:
class PointFSerializable extends PointF implements Serializable
{
public PointFSerializable(PointF pointF) {
super(pointF.x, pointF.y);
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
out.writeFloat(x);
out.writeFloat(y);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
float x = in.readFloat();
float y = in.readFloat();
set(x,y);
}
private void readObjectNoData() throws ObjectStreamException {
set(0f,0f);
}
}
现在我有一个嵌套的 ArrayList
这样的 PointFSerializable
对象,它是 serializable
因为 ArrayList
和 PointFSerializable
是可序列化的,我可以因此放入 Bundle bundle
如下:
ArrayList<ArrayList<PointFSerializable>> drawingSerializable = new
ArrayList<ArrayList<PointFSerializable>>();
//populate the nested ArrayList
for([...]) {
ArrayList<PointFSerializable> strokeSerializable = new ArrayList<PointFSerializable>();
for([...]) {
strokeSerializable.add(new PointFSerializable(...));
}
drawingSerializable.add(strokeSerializable);
}
//Put it into the Bundle
bundle.putSerializable("Drawing", drawingSerializable);
在另一个函数中,我后来通过 getSerializable()
从 Bundle bundle
中检索了嵌套的 ArrayList
并进行了如下转换:
ArrayList<ArrayList<PointFSerializable>> drawingSerializable = (ArrayList<ArrayList<PointFSerializable>>)bundle.getSerializable("Drawing");
到目前为止一切都按预期工作,但现在我想遍历 drawingSerializable
:
for(ArrayList<PointFSerializable> strokeSerializable : drawingSerializable) {
for(PointFSerializable pointFSerializable : strokeSerializable) { //<--
[...]
}
}
在标有 <--
的行中,我得到一个
java.lang.ClassCastException: android.graphics.PointF cannot be cast to com.cgogolin.myapp.PointFSerializable
这是我不明白的。
我本以为这个错误是 strokeSerializable
类型 ArrayList<PointF>
,但是,显然它不应该是,因为我将它定义为 ArrayList<PointFSerializable>
类型,如果它如果不是那种类型,那么我预计已经在外部 for 循环中得到一个错误。
现在,在内部 for 循环的主体中,我无论如何都想将 pointFSerializable
转换为 PointF
。因此,我可以用
for(PointF pointF : strokeSerializable) {
然后一切正常。但是为什么?
为什么,从 bundle.getSerializable("Drawing");
,我显然取回了一些我可以像 ArrayList<ArrayList<PointF>>
一样对待的东西(它甚至不是一个可序列化的对象!)但不像 ArrayList<ArrayList<PointFSerializable>>
,即使我将后一种类型的对象放入 Bundle?
PointF 是可打包的,这意味着您可以将标准 PointF 打包。如果 class 既可序列化又可打包,Android 将延迟写入和读取包裹。发生的事情是因为您没有覆盖分割方法,Android 将您的对象分割为标准 PointF。如果您需要能够在 class 之外序列化您的 class,请确保重写 Parcelable 接口中所需的方法。