从包中存储和检索自定义可序列化 class 的 ArrayList

Store and retrieve ArrayList of custom serializable class from bundle

我知道在 Whosebug 上有很多关于在 Bundles 中存储 ArrayLists 的问题,但即使阅读了其中的许多问题和文档,我还是不明白我在下面描述的问题.我并不是在寻求解决这个特定编程问题的帮助,因为我有一个 "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 因为 ArrayListPointFSerializable 是可序列化的,我可以因此放入 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 接口中所需的方法。