Serializable 和 Parcelable 的用法和区别

1. Serializable 和 Parcelable 的用法

Android 开发过程中,需要对对象进行存储和传递,而对于对象的存储传递就需要用到 Serializable 和 Parcelable 对对象进行序列化和反序列化。

1.1 Serializable 的使用

对象类实现 Serializable 接口,并定义 serialVersionUID:

package cn.zzw.serialzilable.demo;

import java.io.Serializable;

/**
 * @author 鹭岛猥琐男
 * @create 2019/10/13 9:22
 */
public class UserInfo implements Serializable {
    private static final long serialVersionUID = 2193374790529803008L;
    private String userName;
    private int age;

    public UserInfo(String userName, int age) {
        this.userName = userName;
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}

1.2 Parcelable 的使用

对象类实现接口 Parcelable,目前 AndroidStudio 已经有专门的插件来实现:

package cn.zzw.serialzilable.demo;

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

/**
 * @author 鹭岛猥琐男
 * @create 2019/10/13 9:23
 */
public class StudentInfo implements Parcelable {
    private String name;
    private int age;

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }

    public StudentInfo() {
    }

    protected StudentInfo(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }

    public static final Creator<StudentInfo> CREATOR = new Creator<StudentInfo>() {
        @Override
        public StudentInfo createFromParcel(Parcel source) {
            return new StudentInfo(source);
        }

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

    @Override
    public String toString() {
        return "StudentInfo{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

1.3 对象的存储和传递

package cn.zzw.serialzilable.demo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView mTv;
    //保存文件的路径
    private String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/userInfo.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.mBtnSet).setOnClickListener(this);
        findViewById(R.id.mBtnGet).setOnClickListener(this);
        findViewById(R.id.mBtnNext).setOnClickListener(this);
        mTv = findViewById(R.id.mTV);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.mBtnSet:
                UserInfo userInfo = new UserInfo("zuowei.zhang", 31);
                save(userInfo);
                break;
            case R.id.mBtnGet:
                UserInfo info = readInfo();
                if (info != null) {
                    mTv.setText(info.toString());
                } else {
                    mTv.setText("数据为空");
                }
                break;
            case R.id.mBtnNext:
                StudentInfo studentInfo = new StudentInfo("zuowei.zhang", 110);
                Intent intent = new Intent(this, SecondActivity.class);
                intent.putExtra("info", studentInfo);
                startActivity(intent);
                break;
            default:
                break;
        }
    }

    //保存数据
    public void save(UserInfo userInfo) {
        ObjectOutputStream fos = null;
        try {
            File file = new File(path);
            fos = new ObjectOutputStream(new FileOutputStream(file));
            fos.writeObject(userInfo);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
            }
        }
    }

    public UserInfo readInfo() {
        UserInfo userInfo = null;
        ObjectInputStream ois = null;
        try {
            //获取输入流
            ois = new ObjectInputStream(new FileInputStream(new File(path)));
            //获取文件中的数据
            userInfo = (UserInfo) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return userInfo;
    }

}

1.4 结果

 在这个例子中,一开始未向磁盘中写入数据,先从磁盘中读取数据,发现数据为空,接着采用 Serializable 的方式,向磁盘中写入数据,再从磁盘中读取数据并显示。而页面跳转传递数据采用 Parcelable 的方式,在新的页面成功的接收到了对象数据,并成功的显示。

2. Serializable 和 Parcelable 的区别

Serializable 是Java自带的,而 Parcelable是安卓专有的。Serializable 主要用于保存对象的属性到本地文件、数据库、网络流以方便数据传输。Android 的 Parcelable 的设计初衷是因为 Serializable 效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable 是通过 IBinder 通信的消息的载体。Parcelable 的性能比 Serializable 好,在内存开销方面较小,所以在内存间数据传输时推荐使用 Parcelable 。Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择 Serializable 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值