解决Android "Parcelable encountered IOException writing serializable object (name =X$x)"

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = XXX$1$1),好好的代码无意间报这个错,Caused by: java.io.NotSerializableException:。。。看到这个我不慌,明显的序列化失败了,而且XXX$1明显是内部类没有实现java.io.Serializable接口;但是当前类里面有好几个内部类引用,$1让人看着难受

一般出现这种问题有两种解决思路

1、让实体类和它的所有内部类都实现java.io.Serializable接口,如果有引用了其他类型的字段属性,该类型也得实现java.io.Serializable
2、如果实体类中有基本数据类型则尽可能的用对应的包装类(如:boolean用Boolean),List用ArrayList,因为ArrayList默认实现了java.io.Serializable;其他的集合也一样

public class A implements Serializable {

    /**
     * 内部类
     */
    B b;
    /**
     * 外部引用类型
     */
    C c;
    /**
     * int和Integer是有自动拆装箱机制,但是要是参与序列化还是用包装类比较好
     */
    Integer d;
    Boolean e;
    /**
     * String 默认实现Serializable
     */
    String f;
    
     ArrayList<String> e;
    
    HashMap<String,String> f;
    
    class  B implements Serializable{
        
    }
}
class C implements Serializable{
    
}

上面就是最常规的操作,注意:我为了方便用字母来命名了,还有就是公司有安全规定,所以只能写这么潦草了

接下来要说的是我遇到一个不常规的,就是饮用类型是个接口,并且接口继承于Serializable,然后在用Bundle传值的时候报错了。

public class A implements Serializable {

    /**
     * 内部类
     */
    B b;
    /**
     * 外部引用类型
     */
    C c;
    /**
     * int和Integer是有自动拆装箱机制,但是要是参与序列化还是用包装类比较好
     */
    Integer d;
    Boolean e;
    /**
     * String 默认实现Serializable
     */
    String f;

    ArrayList<String> e;

    HashMap<String,String> f;
    /**
     * 这里我是通过匿名对象传值的,然后就报错了
     */
    Z z;
    class  B implements Serializable{

    }
}
class C implements Serializable{

}

/**
 * 定义了一个接口,继承自序列化接口
 */
interface Z extends Serializable{
    void doSomeThing();
}

在上面代码的基础上添加了interface Z 后就出现了问题,刚开始排查不到,主要是log显示的不明确全是系统的log,后来才把问题定位到 class A中,但是我看了所有的内部类和外部类还有数据类型都是按照上面两个点来的,应该没啥问题;后来就采用控制变量法,注释掉一个字段跑一遍,终于在把interface Z注释后程序正常了。

  • 一般按照Java语法interface Z extends Serializable好像没毛病,但是后来参考List和ArrayList的设计才发现人家的序列化接口不是放在接口中搞的,而是在具体实现类中搞的,List是接口,其子类ArrayList不经实现了List接口,同时还实现了java.io.Serializable和其他接口
  • 所以上面代码进一步修改如下,可以实现我们的需求
public class A implements Serializable {

    /**
     * 内部类
     */
    B b;
    /**
     * 外部引用类型
     */
    C c;
    /**
     * int和Integer是有自动拆装箱机制,但是要是参与序列化还是用包装类比较好
     */
    Integer d;
    Boolean e;
    /**
     * String 默认实现Serializable
     */
    String f;

    ArrayList<String> e;

    HashMap<String,String> f;
    /**
     * Y就OK了
     */
    Y z;
    class  B implements Serializable{

    }
}
class C implements Serializable{

}

/**
 * 定义了一个接口,继承自序列化接口
 */
interface Z{
    void doSomeThing();
}

class Y implements Z,Serializable{
    @Override
    public void doSomeThing() {

    }
}

坑是填上了,但是有很多疑惑,待大神为我分析为啥不能用interface Z extends Serializable

在这里插入图片描述

发布了117 篇原创文章 · 获赞 56 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/Jiang_Rong_Tao/article/details/100034448