Android,androidsdk

來源:互聯網
上載者:User

Android,androidsdk
Serializable

  • 靜態變數序列化不會被儲存
public class Test implements Serializable {    private static final long serialVersionUID = 1L;    public static int staticVar = 5;    public static void main(String[] args) {        try {            //初始時staticVar為5            ObjectOutputStream out = new ObjectOutputStream(                    new FileOutputStream("result.obj"));            out.writeObject(new Test());            out.close();            //序列化後修改為10            Test.staticVar = 10;            ObjectInputStream oin = new ObjectInputStream(new FileInputStream(                    "result.obj"));            Test t = (Test) oin.readObject();            oin.close();                        //再讀取,通過t.staticVar列印新的值            System.out.println(t.staticVar);                    } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}

最後的輸出是 10

  • 父類的序列化與 Transient 關鍵字

一個子類實現了 Serializable 介面,它的父類都沒有實現 Serializable 介面,序列化該子類對象,然後還原序列化後輸出父類定義的某變數的數值,該變數數值與序列化時的數值不同。

要想將父類對象也序列化,就需要讓父類也實現Serializable 介面。如果父類不實現的話的,就 需要有預設的無參的建構函式。如果你考慮到這種序列化的情況,在父類無參建構函式中對變數進行初始化,否則的話,父類變數值都是預設聲明的值,如 int 型的預設是 0,string 型的預設是 null。

我們熟悉使用 Transient 關鍵字可以使得欄位不被序列化,那麼還有別的方法嗎?根據父類對象序列化的規則,我們可以將不需要被序列化的欄位抽取出來放到父類中,子類實現 Serializable 介面,父類不實現,根據父類序列化規則,父類的欄位資料將不被序列化。

  • 序列化儲存規則
ObjectOutputStream out = new ObjectOutputStream(                    new FileOutputStream("result.obj"));    Test test = new Test();    //試圖將對象兩次寫入檔案    out.writeObject(test);    out.flush();    System.out.println(new File("result.obj").length());    out.writeObject(test);    out.close();    System.out.println(new File("result.obj").length());    ObjectInputStream oin = new ObjectInputStream(new FileInputStream(            "result.obj"));    //從檔案依次讀出兩個檔案    Test t1 = (Test) oin.readObject();    Test t2 = (Test) oin.readObject();    oin.close();                //判斷兩個引用是否指向同一個對象    System.out.println(t1 == t2);

對同一對象兩次寫入檔案,列印出寫入一次對象後的儲存大小和寫入兩次後的儲存大小,然後從檔案中還原序列化出兩個對象,比較這兩個對象是否為同一對象。一般的思維是,兩次寫入對象,檔案大小會變為兩倍的大小,還原序列化時,由於從檔案讀取,產生了兩個對象,判斷相等時應該是輸入 false 才對,但是。。。

android.os.BadParcelableException: ClassNotFoundException when unmarshalling

public Config config;public RowView(Parcel in){    type = in.readString();    interfaceUrl = in.readString();    size = in.readInt();    config = in.readParcelable(null);}

報錯的語句即為config = in.readParcelable(null);

  • 分析

根據android文檔介紹:

readParcelable (ClassLoader loader)

loader A ClassLoader from which to instantiate the Parcelable object, or null for the default class loader.即loader為空白時系統會採取預設的class loader。

Android有兩種不同的classloaders:framework classloader和apk classloader,其中framework classloader知道怎麼載入android classes,apk classloader知道怎麼載入you code,apk classloader繼承自framework classloader,所以也知道怎麼載入android classes。

在應用剛啟動時,預設class loader是apk classloader,但在系統記憶體不足應用被系統回收會再次啟動,這個預設class loader會變為framework classloader了,所以對於自己的類會報ClassNotFoundException。

  • 解決

 

將config = in.readParcelable(null);改為config = in.readParcelable(Config.class.getClassLoader());

Config.class.getClassLoader()即為apk classloader, 其中Config.class可以改為你程式中自己寫的任意類,因為他們同樣指向apk loader。

試著改為config = in.readParcelable(Activity.class.getClassLoader());你會發現依然ClassNotFoundException因為Activity.class.getClassLoader()指向的是framework classloader

我是天王蓋地虎的分割線

 

 

參考:http://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.