Serializable和Parcelable在Android中传递值对象时的使用粗略讲解

本文深入探讨了Android中序列化的两种主要方式:Serializable和Parcelable的区别及其应用场景。对比了它们的性能特点,介绍了如何实现自定义类的序列化过程,并提供了具体的代码示例。

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

在Android中,我们会频繁地使用到值传递Intent、Bundle,有时候传递的是int或者String等系统提供的值类型,但有时候要传递自定义的类型,比如用户User。这时我们就要用到Serializable或者Parcelable用于对自定义数据进行序列化

两者区别:
Serializable:是Java提供的序列化接口,所有序列化操作由系统完成,方便但是速度比较慢,效率低。

Parcelable:是Android提供的序列化接口,需要手动完成部分操作(操作详细见下面内容),有些许复杂但是速度快,效率高


实现Parcelable就是为了进行序列化,那么,为什么要序列化?

1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
4)选择序列化方法的原则


注意

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
4)需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口。

————————————————

User自定义类代码:


public class User {
    private String userName;
    private int userAge;

    public String getUserName(){
        return userName;
    }
    public void setUserName(String userName){
        this.userName = userName;
    }

    public int getUserAge(){
        return userAge;
    }
    public void setUserAge(int userAge){
        this.userAge = userAge;
    }
}

————————————————

Serializable传递User值对象的代码:
首先User类要实现Serializable接口(public class User implements Serializable)

put:
    Intent i = new Intent(......);
    User user = new User();
    user.setUserName("zhangsan");
    user.setUserAge("11");
    i.putExtra("user",user);

get:
    Intent i = getIntent();
    User user = (User) i.getSerializableExtra("user");
    System.out.println(user.getUserName());

————————————————

Parceliable传递User值对象的代码:
首先User类要实现Parceliable接口,并且Override两个方法describeContents()、writeToParcel(),还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口。

简言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,再通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,写的顺序和读的顺序必须一致

  public class User implements Parceliable{

      ......

    @Override
    public int describeContents(){   //这个不用管
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest , int flags){

        dest.writeString(getUserName());
        dest.writeString(getUserAdd());
        dest.writeInt(getUserAge());
    }

    public static final Creator<User> CREATOR = new Creator<User>{

        @Override
        public User createFromParcel(Parcel source){
            User user = new User();
            user.setUserName(source.readString());
            user.setUserAdd(source.readString());
            user.setUserAge(source.readInt());
            return user;  
        }

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

}   

下面是将Uesr对象进行传递的代码

put:
     User user = new User();
     user.setUserName("zhangsan");
     user.setUserAdd("shagnhai");
     user.setUserAge(11);

     Intent i = new Intent(......);
     i.putExtra("user",user);

get:
    Intent i = getIntent();
    User user = i.getParcelableExtra("user");
    System.out.println(user.getUserName());

注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。

————————————————

从上面的代码我们可以看到,Serializable和Parcelable的区别主要是对自定义数据进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AidenWU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值