Android中的數據傳遞之Parcelable接口

對於Android來說傳遞復雜類型,主要是將自己的類轉換為基礎的字節數組,Activity之間傳遞數據是通過Intent實現的。 Android序列化對象主要有兩種方法,實現Serializable接口、或者實現Parcelable接口。實現Serializable接口是Java SE本身就支持的,而Parcelable是Android特有的功能,效率比實現Serializable接口高,而且還可以用在進程間通信(IPC)中。實現Serializable接口非常簡單,聲明一下就可以瞭。而實現Parcelable接口稍微復雜一些,但效率更高,推薦用這種方法提高性能。
Parcelable接口的作用:實現瞭Parcelable接口的實例可以將自身的狀態信息(狀態信息通常指的是各成員變量的值)寫入Parcel,也可以從Parcel中恢復其狀態。
Parcel用來完成數據的序列化傳遞。下面就介紹一下實現Parcelable接口的方法。
通過實現Parcelable接口序列化對象的步驟:

 

1、實現Parcelable接口。

2、並且實現Parcelable接口的public
      void writeToParcel(Parcel dest, int flags)方法

3、自定義類型中必須含有一個名稱為CREATOR的靜態成員,該成員對象要求實現Parcelable.Creator接口及其方法。
      簡而言之:通過writeToParcel將你的對象映射成Parcel對象,再通過createFromParcel將Parcel對象映射成你的對象。也可以將Parcel             看成是一個流,通過writeToParcel把對象寫到流裡面,在通過createFromParcel從流裡讀取對象,隻不過這個過程需要你來實現,因此寫的順序和讀的順序必須一致。

newArray(int size) 創建一個類型為T,長度為size的數組,僅一句話(return new T[size])即可

示例代碼:

[java]
<SPAN style="FONT-SIZE: 18px"><STRONG>import android.os.Parcel;  
import android.os.Parcelable;  
   
public class Person implements Parcelable {  
      //這裡定義瞭兩個變量來說明讀和寫的順序要一致      
     private Integer id;  
     private String name;  
   
     public Person() {  
     }  
   
     public Person(Integer id, String name) {  
           
         this.id = id;  
         this.name = name;  
     }  
   
     public Integer getId() {  
         return id;  
     }  
   
     public void setId(Integer id) {  
         this.id = id;  
     }  
   
     public String getName() {  
         return name;  
     }  
   
     public void setName(String name) {  
         this.name = name;  
     }  
   
     @Override  
     public int describeContents() {  
         return 0;  
     }  
   
     @Override  
     public void writeToParcel(Parcel dest, int flags) {  
         // 把javanbean中的數據寫到Parcel。先寫id然後寫name    
         dest.writeInt(this.id);  
         dest.writeString(this.name);  
     }  
   
     // 添加一個靜態成員,名為CREATOR,該對象實現瞭Parcelable.Creator接口    
     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {  
         @Override  
         public Person createFromParcel(Parcel source) {  
             // 從Parcel中讀取數據,返回person對象    
             return new Person(source.readInt(), source.readString());  
         }  
   
         @Override  
         public Person[] newArray(int size) {  
             return new Person[size];  
         }  
     };  
 } </STRONG></SPAN> 

import android.os.Parcel;
import android.os.Parcelable;
 
public class Person implements Parcelable {
      //這裡定義瞭兩個變量來說明讀和寫的順序要一致   
     private Integer id;
     private String name;
 
     public Person() {
     }
 
     public Person(Integer id, String name) {
         
         this.id = id;
         this.name = name;
     }
 
     public Integer getId() {
         return id;
     }
 
     public void setId(Integer id) {
         this.id = id;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     @Override
     public int describeContents() {
         return 0;
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         // 把javanbean中的數據寫到Parcel。先寫id然後寫name 
         dest.writeInt(this.id);
         dest.writeString(this.name);
     }
 
     // 添加一個靜態成員,名為CREATOR,該對象實現瞭Parcelable.Creator接口 
     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
         @Override
         public Person createFromParcel(Parcel source) {
             // 從Parcel中讀取數據,返回person對象 
             return new Person(source.readInt(), source.readString());
         }
 
         @Override
         public Person[] newArray(int size) {
             return new Person[size];
         }
     };
 }
[java]
<SPAN style="FONT-SIZE: 18px"><STRONG>   1: public class Student implements Parcelable{ 
   2:     private String id; 
   3:     private String name; 
   4:     private String grade; 
   5:   
   6:     // Constructor  
   7:     public Student(String id, String name, String grade){ 
   8:         this.id = id; 
   9:         this.name = name; 
  10:         this.grade = grade; 
  11:     } 
  12:     // Getter and setter methods  
  13:     ……… 
  14:     ……… 
  15:      
  16:     // Parcelling part  
  17:     public Student(Parcel in){ 
  18:         String[] data = new String[3]; 
  19:   
  20:         in.readStringArray(data); 
  21:         this.id = data[0]; 
  22:         this.name = data[1]; 
  23:         this.grade = data[2]; 
  24:     } 
  25:   
  26:     @override 
  27:     public int describeContents(){ 
  28:         return 0; 
  29:     } 
  30:   
  31:     @Override 
  32:     public void writeToParcel(Parcel dest, int flags) { 
  33:         dest.writeStringArray(new String[] {this.id, 
  34:                                             this.name, 
  35:                                             this.grade}); 
  36:     } 
  37:     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
  38:         public Student createFromParcel(Parcel in) { 
  39:             return new Student(in);  
  40:         } 
  41:   
  42:         public Student[] newArray(int size) { 
  43:             return new Student[size]; 
  44:         } 
  45:     }; 
  46: } 
</STRONG></SPAN> 

   1: public class Student implements Parcelable{
   2:     private String id;
   3:     private String name;
   4:     private String grade;
   5: 
   6:     // Constructor
   7:     public Student(String id, String name, String grade){
   8:         this.id = id;
   9:         this.name = name;
  10:         this.grade = grade;
  11:     }
  12:     // Getter and setter methods
  13:     ………
  14:     ………
  15:    
  16:     // Parcelling part
  17:     public Student(Parcel in){
  18:         String[] data = new String[3];
  19: 
  20:         in.readStringArray(data);
  21:         this.id = data[0];
  22:         this.name = data[1];
  23:         this.grade = data[2];
  24:     }
  25: 
  26:     @override
  27:     public int describeContents(){
  28:         return 0;
  29:     }
  30: 
  31:     @Override
  32:     public void writeToParcel(Parcel dest, int flags) {
  33:         dest.writeStringArray(new String[] {this.id,
  34:                                             this.name,
  35:                                             this.grade});
  36:     }
  37:     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
  38:         public Student createFromParcel(Parcel in) {
  39:             return new Student(in);
  40:         }
  41: 
  42:         public Student[] newArray(int size) {
  43:             return new Student[size];
  44:         }
  45:     };
  46: }

[java]
<SPAN style="FONT-SIZE: 18px"><STRONG>import java.util.HashMap; 
  
import android.os.Parcel; 
import android.os.Parcelable; 
  
public class ParcelTest implements Parcelable { 
    private HashMap map; 
  
    public ParcelTest() { 
        map = new HashMap(); 
    } 
  
    public ParcelTest(Parcel in) { 
        map = new HashMap(); 
        readFromParcel(in); 
    } 
  
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
        public ParcelTest createFromParcel(Parcel in) { 
            return new ParcelTest(in); 
        } 
  
        public ParcelTest[] newArray(int size) { 
            return new ParcelTest[size]; 
        } 
    }; 
  
    @Override 
    public int describeContents() { 
        return 0; 
    } 
  
    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
        dest.writeInt(map.size()); 
        for (String s: map.keySet()) { 
            dest.writeString(s); 
            dest.writeString(map.get(s)); 
        } 
    } 
  
    public void readFromParcel(Parcel in) { 
        int count = in.readInt(); 
        for (int i = 0; i < count; i++) { 
            map.put(in.readString(), in.readString()); 
        } 
    } 
  
    public String get(String key) { 
        return map.get(key); 
    } 
  
    public void put(String key, String value) { 
        map.put(key, value); 
    } 
}</STRONG></SPAN> 

import java.util.HashMap;
 
import android.os.Parcel;
import android.os.Parcelable;
 
public class ParcelTest implements Parcelable {
    private HashMap map;
 
    public ParcelTest() {
        map = new HashMap();
    }
 
    public ParcelTest(Parcel in) {
        map = new HashMap();
        readFromParcel(in);
    }
 
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public ParcelTest createFromParcel(Parcel in) {
            return new ParcelTest(in);
        }
 
        public ParcelTest[] newArray(int size) {
            return new ParcelTest[size];
        }
    };
 
    @Override
    public int describeContents() {
        return 0;
    }
 
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(map.size());
        for (String s: map.keySet()) {
            dest.writeString(s);
            dest.writeString(map.get(s));
        }
    }
 
    public void readFromParcel(Parcel in) {
        int count = in.readInt();
        for (int i = 0; i < count; i++) {
            map.put(in.readString(), in.readString());
        }
    }
 
    public String get(String key) {
        return map.get(key);
    }
 
    public void put(String key, String value) {
        map.put(key, value);
    }
}
android 中自定義的對象序列化的問題有兩個選擇一個是Parcelable,另外一個是Serializable。
一 序列化原因:

1.永久性保存對象,保存對象的字節序列到本地文件中;
2.通過序列化對象在網絡中傳遞對象;
3.通過序列化在進程間傳遞對象。

二 至於選取哪種可參考下面的原則:

1.在使用內存的時候,Parcelable 類比Serializable性能高,所以推薦使用Parcelable類。
2.Serializable在序列化的時候會產生大量的臨時變量,從而引起頻繁的GC。
3.Parcelable不能使用在要將數據存儲在磁盤上的情況,因為Parcelable不能很好的保證數據的持續性在外界有變化的情況下。盡管Serializable效率低點, 也不提倡用,但在這種情況下,還是建議你用Serializable 。

You May Also Like