Android 序列化对象Parcelable 的使用

本文深入探讨了Android应用内部及跨程序间数据传输中,Serializable和Parcelable两种机制的区别与应用场景。重点阐述了它们的效率差异、编程实现方式,并通过实例展示了如何实现Parcelable接口以优化内存数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1、作用

Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

从上面的设计上我们就可以看出优劣了。

 

2、效率及选择

Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

 

3、编程实现

对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。而Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义,而序列化的这些操作完全由底层实现

Parcelable接口:

   内容描述接口,没什么作用
    
public int describeContents();
    写入接口函数,用来打包
    
public void writeToParcel(Parcel dest, int flags);
    读取接口,目的是从parcel中构造一个实现了parcelable的类的实例对象,因为实现类这里是不可知的,所以需要用到模板的方法,继承类通过模板参数传入。
    为了能够实现模板参数的传入,定义了creator嵌入接口,内涵两个接入函数分别是单个和多个继承类实例。
    public interface Creator<T> {
         public T createFromParcel(Parcel source);
         public T[] newArray(int size);
    }
    还有一个子接口继承Creator,子接口只提供了一个函数,返回单个继承类实例
    public interface ClassLoaderCreator<T> extends Creator<T>






import java.util.ArrayList;
import java.util.List;

import android.os.Parcel;
import android.os.Parcelable;


/**
 * 相册类
 *
 * */
public class Album implements Parcelable{
    
//    相册属性id,名字和相册的url
    private String id,name,pic_url;
//    每个相册中存放的照片
    private List<Picture> pics;

    public Album()
    {
        
    }
    
    public  Album(Parcel in){
        id=in.readString();
        name=in.readString();
        pic_url=in.readString();
        pics=new ArrayList<Picture>();
        in.readArrayList(Picture.class.getClassLoader());
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPic_url() {
        return pic_url;
    }

    public void setPic_url(String pic_url) {
        this.pic_url = pic_url;
    }

    public ArrayList<Picture> getPics() {
        return (ArrayList<Picture>) pics;
    }

    public void setPics(ArrayList<Picture> pics) {
        this.pics = pics;
    }

    
    
    
    public static final Parcelable.Creator<Album> album=new Creator<Album>() {
        
        @Override
        public Album[] newArray(int size) {
            // TODO Auto-generated method stub
            return new Album[size];
        }
        
        @Override
        public Album createFromParcel(Parcel source) {
            // TODO Auto-generated method stub
            return new Album(source);
        }
    };
    
    
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO Auto-generated method stub
        dest.writeString(id);
        dest.writeString(name);
        dest.writeString(pic_url);
        dest.writeList(pics);
    }
    
}



注意:从上面我们可以看出Parcel的写入和读出顺序是一致的。如果元素是list读出时需要先new一个ArrayList传入,否则会报空指针异常。如下:

  1. list = new ArrayList<String>();  
  2. in.readStringList(list); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值