Android序列化:Parcelable

本文详细介绍了Android中特有的序列化方式——Parcelable,作为高效的数据传递方式,它基于内存进行序列化和反序列化。文章对比了Parcelable与Serializable的区别,并展示了如何实现Parcelable接口,包括writeToParcel和createFromParcel的方法实现。

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

一、概述

在上一篇中我们介绍了Java中的序列化方式(也能用于Android),详情:Java Serializable(序列化),本篇继续介绍Android中特有的序列化方式:Parcelable,它也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。

Parcelable是Android中进行跨进程间通信传递数据的方式,它基于内存进行序列化和反序列化,因此效率较高。Parcelable定义了将数据写入Parcel,和从Parcel中读出数据的接口。一个实体(用类来表示),如果需要封装到消息中去,就必需实现这一接口。其中Parcel的作用:它提供一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读取出字节流,并反序列化成对象。

二、Parcelable接口定义

public interface 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);
    }
}

三、应用Parcelable

public class User implements Parcelable {
    public String name;
    public int age;

    private User(Parcel in) {
        // 按照写入的顺序依次从Parcel中恢复对象字段值
        name = in.readString();
        age = in.readInt();
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 反序列化过程(从Parcel读取数据)
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    // 序列化过程(将数据写入Parcel)
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 将各个字段按照顺序写入流中
        dest.writeString(name);
        dest.writeInt(age);
    }
}
以下是测试Activity
public class TestActivity extends Activity {
    private static final String TAG = TestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);

        Parcel parcel = Parcel.obtain();
        User user = new User("aronchen", 28);
        //写入Parcel
        parcel.writeParcelable(user, 0);
        //Parcel读写共用一个位置计数,这里一定要重置一下当前的位置
        parcel.setDataPosition(0);
        //读取Parcel
        User user1 = parcel.readParcelable(User.class.getClassLoader());
        Log.e(TAG, "user.name:" + user1.name + "; user.age:" + user1.age);
    }

}

可以看出,使用Parcelable接口稍微麻烦点,和Serializable相比,我们需要在writeToParcel中按序将各个字段写入到流中,同样,在createFromParcel中我们需要自己返回一个User对象。其中的CREATOR用到了代理设计模式。

三、Parcelable与Serializable的区别

SerializableParcelable
Java SE、Android通用Android专用
需要大量I/O操作,效率低内存序列化,效率高
使用较方便使用较复杂






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值