解決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

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章