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])即可

示例代码:

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]; 
         } 
     }; 
 } 

   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: }

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 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值