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 。