日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
對象的序列化存儲:Serializable和Parceable

在進行Android開發(fā)的時候我們有時候需要用到數(shù)據(jù)的持久化存儲,或者在進程之間傳遞數(shù)據(jù)。其中就可能需要用到對象的序列化,經(jīng)過序列化的對象之后可以通過Intent或者Boundle來傳輸了。接下來還是想些介紹下吧。

創(chuàng)新互聯(lián)秉承實現(xiàn)全網(wǎng)價值營銷的理念,以專業(yè)定制企業(yè)官網(wǎng),網(wǎng)站建設、成都網(wǎng)站設計,小程序開發(fā),網(wǎng)頁設計制作,成都做手機網(wǎng)站,成都全網(wǎng)營銷幫助傳統(tǒng)企業(yè)實現(xiàn)“互聯(lián)網(wǎng)+”轉型升級專業(yè)定制企業(yè)官網(wǎng),公司注重人才、技術和管理,匯聚了一批優(yōu)秀的互聯(lián)網(wǎng)技術人才,對客戶都以感恩的心態(tài)奉獻自己的專業(yè)和所長。

1.什么叫序列化,什么叫反序列化

序列化: 將數(shù)據(jù)結構或?qū)ο筠D換成二進制串的過程。反序列化:將在序列化過程中所生成的二進制串轉換成數(shù)據(jù)結構或者對象的過程。

簡單來說,序列化就是將我們生成的對象進行存儲起來(比如磁盤上),以用來將來使用或者在網(wǎng)絡上進行傳輸,而反序列化呢,就是由我們的之前序列化生成的二進制串重新生成對象的過程。注意,這里我們反復說的序列化啦,反序列化啦,都是針對的對象,而非類。因為我們是針對對象進行存取與傳輸?shù)?,而非類,當我們需要重新獲取之前的對象的時候,是直接讀取出來的(從文件或網(wǎng)絡中),而非根據(jù)類new出一個對象,這點是需要注意的。

2.如何序列化

序列話的方式有兩種,一種是實現(xiàn)Serializable接口,一種是實現(xiàn)Parceable接口,下面會具體介紹這兩種方式。

a.實現(xiàn)Serializable接口

這種序列化方式是Java提供的,它的優(yōu)點是簡單,其實Serializable接口是個空接口,因而我們并不需要實現(xiàn)什么抽象方法,但是我們卻往往需要在類中聲明一個靜態(tài)變量標識(serialVersionUID),但這不是必須的,我們不聲明,依然可以實現(xiàn)序列化,但是這樣的話會對反序列化產(chǎn)生一定的影響,可能會在我們對類做了修改之后而造成對象的反序列化失敗。聲明方式如下:

 
 
 
 
  1. private static final long serialVersionUID = 8711368828010083044L; 

注意,這里的值可以是任意值。

下面我們來具體實現(xiàn)下。

 
 
 
 
  1. package com.qc.admin.myserializableparceabledemo; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. /** 
  6.  * Created by admin on 2016/12/1. 
  7.  */ 
  8.  
  9. public class User implements Serializable { 
  10.  
  11.     private static final long serialVersionUID = 519067123721295773L; 
  12.  
  13.     public int userId; 
  14.     public String userName; 
  15.     public boolean isMale; 
  16.  
  17.     public User(int userId, String userName, boolean isMale) { 
  18.  
  19.         this.userId = userId; 
  20.         this.userName = userName; 
  21.         this.isMale = isMale; 
  22.  
  23.     } 
  24.  
  25.     @Override 
  26.     public String toString() { 
  27.         return "User{ " + 
  28.                 "userId = " + userId + 
  29.                 ", userName = " + userName + 
  30.                 ", isMale = " + isMale + 
  31.                 " }"; 
  32.     } 
  33. }  

下面是序列化與反序列化過程: 

 
 
 
 
  1. private void beginSerizable() throws IOException, ClassNotFoundException { 
  2.  
  3.         // 序列化 
  4.         User user = new User(2016, "qian", true); 
  5.         ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File(getFilesDir(), "myfile.txt"))); 
  6.         out.writeObject(user); 
  7.         out.close(); 
  8.  
  9.         // 反序列化 
  10.         // 注意,這里后面的“/myfile.txt”前面有個斜杠“/”,否則會報“FileNotFoundException”異常 
  11.         ObjectInputStream in = new ObjectInputStream(new FileInputStream(getFilesDir() + "/myfile.txt")); 
  12.         User mUser = (User) in.readObject(); 
  13.         textView.setText(mUser.toString()); 
  14.         in.close(); 
  15.         Log.i("test",mUser.toString()); 
  16.     }  

運行結果截圖: 

注意:如果是在Android項目中調(diào)用以上方法,別忘了在Manifest.xml文件中配置如下權限:

 
 
 
 
  1.  
  2.   

b.實現(xiàn)Parceable接口

這種方式是Android提供的方式,相比較前面那種方式來講,這種方式稍微有點復雜,我們需要自己盡享序列化與反序列化的操作,但是它卻更加高效,并不需要執(zhí)行大量的I/O操作。而且這種方式也是Android推薦的序列化方式,因此我們應該***Parceable。只要實現(xiàn)了這個接口,一個類的對象就可以實現(xiàn)序列化并可以通過Intent和Binder進行傳遞了。下面請看實例: 

 
 
 
 
  1. public class Book implements Parcelable { 
  2.     public String bookTitle; 
  3.     public int bookId; 
  4.  
  5.     protected Book(Parcel in) { 
  6.         bookTitle = in.readString(); 
  7.         bookId = in.readInt(); 
  8.     } 
  9.  
  10.     public static final Creator CREATOR = new Creator() { 
  11.         @Override 
  12.         public Book createFromParcel(Parcel in) { 
  13.             return new Book(in); 
  14.         } 
  15.  
  16.         @Override 
  17.         public Book[] newArray(int size) { 
  18.             return new Book[size]; 
  19.         } 
  20.     }; 
  21.  
  22.     @Override 
  23.     public int describeContents() { 
  24.         return 0; 
  25.     } 
  26.  
  27.     @Override 
  28.     public void writeToParcel(Parcel parcel, int i) { 
  29.         parcel.writeString(bookTitle); 
  30.         parcel.writeInt(bookId); 
  31.     } 
  32. }  

這里將Book這個類就實現(xiàn)了Parcelable接口,其實在Android Studio IDE中,上述過程很簡單,我們只需要定義一個類,實現(xiàn)Parcelable接口,然后在里面定義我們的屬性或者說是字段,根據(jù)提示的錯誤,按照它提示的方法覆蓋相應的方法,之后的一切其實都可以自動生成(不過如果需要構造方法的話,那就需要自動生成了,toString()方法也是自己實現(xiàn)的),所以不用擔心在Android開發(fā)中通過實現(xiàn)Parceable接口會比較麻煩,因為AS都會為你自動生成。上面我們已經(jīng)完整的將Book類實現(xiàn)了Parceable接口,那接下來如何序列化和反序列化呢?如果你說,剛才不是已經(jīng)說過了嗎,采用文件讀取的方式不久可以了啦...當你那樣做的時候,你會發(fā)現(xiàn)會報如下的錯誤: 

Why???...什么情況?提示我們Book類沒有實現(xiàn)序列化:

 
 
 
 
  1. /System.err: java.io.NotSerializableException: com.qc.admin.myserializableparceabledemo.Book 

好啦,之所以出現(xiàn)這種問題,并不是我們的實現(xiàn)過程有問題,而是使用該類的方式行不通。到這里我們就明白了Serializable和Parceable兩種方式實現(xiàn)序列化還是有區(qū)別的,剛才我們也講了,Parceable更加高效,不會像Serializable那樣有大量的I/O操作,這句話的具體含義就道出了Serializable與Parcelable區(qū)別:雖然兩者都是用于支持序列化、反序列化話操作,但是兩者***的區(qū)別在于存儲媒介的不同,Serializable是將序列化后的對象存儲在硬盤上,使用I/O讀寫的方式,而Parcelable是將其存儲在內(nèi)存中,是針對內(nèi)存的讀寫,熟悉計算機組成原理的朋友都知道,內(nèi)存的讀寫速度顯然要遠遠大于I/O的讀寫速度,這也是為什么Android中推薦使用Parcelable這種方式來實現(xiàn)對象的序列化。

那我們應該怎么使用通過實現(xiàn)Parcelable接口實現(xiàn)序列化的對象呢?答案是:通過Intent方式傳遞,除了基本類型外,Intent只能傳輸序列化之后的對象,對應這兩種序列化方式,也有兩種相應的方法:

 
 
 
 
  1. mIntent.getSerializableExtra(string name );  
 
 
 
 
  1. mIntent.getParcelableExtra(String name ); 

當然,放入的操作就沒有這種區(qū)分了,都是方法:

 
 
 
 
  1. mIntent.putExtra(); 

我們可以在***個Activity中將序列化對象放入Intent,在另一個Activity中取出,比如:在另一端獲取對象,例如: 

 
 
 
 
  1. Bundle mBundle = getIntent().getExtras(); 
  2. Book mBook = mBundle.getParcelable("book1");  

下面再看類User實現(xiàn)Parceable接口的過程,它內(nèi)部包含了一個可序列化的類Book,具體細節(jié)跟上面的有點不同:

 
 
 
 
  1. package com.qc.admin.myserializableparceabledemo; 
  2.  
  3. import android.os.Parcel; 
  4. import android.os.Parcelable; 
  5.  
  6. /** 
  7.  * Created by admin on 2016/12/1. 
  8.  */ 
  9.  
  10. public class User implements Parcelable { 
  11.  
  12.     public int userId; 
  13.     public String userName; 
  14.     public boolean isMale; 
  15.     public Book book; 
  16.  
  17.  
  18.     public User(int userId, String userName, boolean isMale, Book book) { 
  19.  
  20.         this.userId = userId; 
  21.         this.userName = userName; 
  22.         this.isMale = isMale; 
  23.         this.book = book; 
  24.     } 
  25.  
  26.  
  27.     protected User(Parcel in) { 
  28.         userId = in.readInt(); 
  29.         userName = in.readString(); 
  30.         isMale = in.readByte() != 0; 
  31.         // 此為不同之處1 
  32.         // 也可以通過這種方式:book = in.readParcelable(Thread.currentThread().getContextClassLoader()); 
  33.         book = in.readParcelable(Book.class.getClassLoader()); 
  34.          
  35.     } 
  36.  
  37.     public static final Creator CREATOR = new Creator() { 
  38.         @Override 
  39.         public User createFromParcel(Parcel in) { 
  40.             return new User(in); 
  41.         } 
  42.  
  43.         @Override 
  44.         public User[] newArray(int size) { 
  45.             return new User[size]; 
  46.         } 
  47.     }; 
  48.  
  49.  
  50.     // 幾乎在所有的情況下都應該返回0,只有在當前對象中存在文件描述的時候,此方法返回CONTENTS_FILE_DESCRIPTOR(常量值為1) 
  51.     @Override 
  52.     public int describeContents() { 
  53.         return 0; 
  54.     } 
  55.  
  56.     // 將對象寫入序列化結構中,其中i標識有兩種值,0或者1(PARCELABLE_WRITE_RETURN_VALUE) 
  57.     // 為1時表示當前對象需要作為返回值返回,不能立即釋放資源,幾乎所有情況都為0 
  58.     @Override 
  59.     public void writeToParcel(Parcel parcel, int i) { 
  60.         parcel.writeInt(userId); 
  61.         parcel.writeString(userName); 
  62.         // 注意這里,并不是直接寫入boolean值,而是寫入整數(shù)值 
  63.         parcel.writeByte((byte) (isMale ? 1 : 0)); 
  64.         // 此為不同之處2 
  65.         parcel.writeParcelable(book, i); 
  66.     } 
  67.  
  68.     @Override 
  69.     public String toString() { 
  70.         return "User{ " + 
  71.                 "userId = " + userId + 
  72.                 ", userName = " + userName + 
  73.                 ", isMale = " + isMale + 
  74.                 "book = " + book.toString() + 
  75.                 " }"; 
  76.     } 
  77.  
  78. }  

可以看出,結果已經(jīng)正確的打印了出來了: 

注意:在 Parcelable 中,我們無法直接寫入 boolean 值,而是將其轉化為整數(shù)值進行保存,這里為 Byte,當然,你也可以使用 Int 等。


網(wǎng)站名稱:對象的序列化存儲:Serializable和Parceable
網(wǎng)址分享:http://www.dlmjj.cn/article/cdcjicj.html