【问题标题】:Deserialize an array of Image Objects反序列化图像对象数组
【发布时间】:2013-03-19 12:23:35
【问题描述】:

我有以下课程:

public class DetailedProduct implements Serializable {
    //attributes + get and set
    private Colour colour;
    //get+set

  public class Colour implements Serializable{
     private ArrayList<Image> images;
    //get+set

    public Image[] getImages() {
      return images.toArray(new Image[images.size()]);
    }
  }

  public class Image implements Serializable{

    private static final long serialVersionUID = 3460333138445770749L;
    private String image1;
    private String image2;
    private String image3;

        //get/set methods
  }
 }

我随后创建了一个 Intent 如下

  DetailedProduct.Colour mCurrentColour;
  Intent myIntent = new Intent(DetailsActivity.this, ImageGallery.class);
  myIntent.putExtra("Images", mCurrentColour.getImages());
  startActivity(myIntent);

现在我在 ImageGallery 类中尝试了以下代码:

   Serializable extras = getIntent().getSerializableExtra("Images");
    if (extras != null) {
        images = (Image[]) extras;
    }

但我有以下例外: java.lang.RuntimeException:无法启动活动 ComponentInfo{com./com.productdetails.ProductImageGallery}:java.lang.ClassCastException:java.lang.Object[] 无法转换为 com.productdetails.DetailedProduct$Image[]

如何正确地将可序列化转换为 Image 数组

【问题讨论】:

  • 请添加getImages()的代码并链接一个最小活动
  • @Raffaele 请查看更新
  • 你真的需要内部类(即非静态的)吗?

标签: java android deserialization


【解决方案1】:

快速思考,您可以简单地将图像制作成 bytearray[],并且由于咬数组是可序列化的原始类型。

【讨论】:

    【解决方案2】:

    您将图像作为 arrayList 传递。但是你把它当作一个数组..

    使用以下代码

    Serializable extras = getIntent().getSerializableExtra("Images");
        if (extras != null) {
            images = (ArrayList<Image>) extras;
        }
    

    【讨论】:

    • 他没有展示Colour.getImages()的实现。它当然可以返回一个数组而不仅仅是列表成员
    【解决方案3】:

    你的施法不正确

     java.lang.ClassCastException: java.lang.Object[] cannot be cast to com.productdetails.DetailedProduct$Image[]
    

    你给 Intent 一个 ListArray,然后你尝试用数组来投射它

    这行不正确

     if (extras != null) {
            images = (Image[]) extras;
        }
    

    替换为

     if (extras != null) {
            images = (ListArray<Image>) extras;
        }
    

    【讨论】:

    • Object[] 不能转换为 Image[]。这意味着它是一个对象数组,而不是一个列表
    【解决方案4】:

    Android 运行时无法序列化数组。数组类型仍然实现Serializable,但是当它从Intent使用的Bundle返回时,它丢失了所有信息(包括类型,始终为Ljava.lang.Object。网上的一些答案建议使用Parcelable ,但是我尝试并没有成功。

    可以实现的是传输Parcelable 对象的集合,但以ArrayList 的形式,这也恰好是您在原始样本中使用的数据结构。调用代码如下:

    Intent intent = new Intent(this, Target.class);
    ArrayList<Foo> data = new ArrayList<Foo>();
    data.add(new Foo());
    
    intent.putParcelableArrayListExtra("data", data);
    intent.putExtra("serializable", new Foo[] {new Foo()});
    startActivity(intent);
    

    我使用了名为Foo 的常用虚拟类,但请注意,实现Parcelable 非常乏味。此外,它要求您的类有一个名为 CREATORParcelable.Creator&lt;T&gt; 类型的 static 字段,而对于内部类型,这在 Java 语言中根本不可能。这就是为什么您必须切换到嵌套(静态)类,最终在构造函数中传递您当前的 outer 实例并相应地更改字段可见性(从 privatepublic 或包私有) .顺便说一句,这也将提高你的代码库的可测试性,因为你减少了耦合。我的意思是,而不是这个不可编译的来源:

    public class Product implements Parcelable {
      public class Color implements Parcelable {
        public static final Parcelable.Creator<Color> CREATOR; // Illegal!!!
      }
    }
    

    类似的东西

    public class Product implements Parcelable{
      public static class Color implements Parcelable {
        public Color(Product exOuter) {
        }
      }
    }
    

    但请注意,这样您将无法访问封闭类的非静态成员,因此将Color 移出Product 可能会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-11
      • 2015-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多