序列化:Serializable、Parcelable、JSON
大半个月没更新了,最近事情太多了,还有点懒。。。
不说了,继续更,正文开始
Serializable
Serializable是Java提供的序列化接口,使用方式也很简单,只要实现该接口就行了,实现了序列化后,我们就可以通过ObjectOutputStream
把对象转成字节流,并且通过ObjectInputStream
解析成对象
下文以Student
类和Score
类为例:
package com.example.serializationdemo;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private int age;
private Score score;
public Student(String name, int age, Score score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Score getScore() {
return score;
}
public void setScore(Score score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
class Score implements Serializable {
private int math;
private int english;
public Score(int math, int english) {
this.math = math;
this.english = english;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
@Override
public String toString() {
return "Score{" +
"math=" + math +
", english=" + english +
'}';
}
}
然后我们对这个对象进行存储和解析
// 把对象转成字节流,存储为文件student.data
public void save(View view) {
Student student = new Student("Tom", 20, new Score(60, 61));
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(openFileOutput("student.data", MODE_PRIVATE));
objectOutputStream.writeObject(student);
objectOutputStream.flush();
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 从文件中读取并解析成对象
public void load(View view) {
try {
ObjectInputStream objectInputStream = new ObjectInputStream(openFileInput("student.data"));
Student student = (Student) objectInputStream.readObject();
textView.setText(student.toString());
objectInputStream.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
Parcelable
Parcelable是Android提供的序列化接口,使用相对于Serializable稍复杂些,但是在效率方面要快很多
下面以User
类为例:
package com.example.serializationdemo;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
protected User(Parcel in) {
name = in.readString();
age = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
@Override
public int describeContents() {
return 0;
}
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];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
可以看到多了两个实现方法、一个构造方法和CREATOR
变量
接着我们就可以在Activity之间传递了
Activity1:
public void useParcelable(View view) {
User user = new User("Jack", 20);
Intent intent = new Intent(this, ParcelableActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("user", user);
intent.putExtra("data", bundle);
startActivity(intent);
}
Activity2:
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("data");
User user = bundle.getParcelable("user");
textView.setText(user.toString());
当然可以直接通过intent.putExtra("user", user);
和User user = intent.getParcelableExtra("user");
实现,只不过放到Bundle中便于管理
JSON
JSON全称JavaScript Object Notation
,一种轻量的文本数据格式,相比于xml数据格式,更加简洁,JSON中包括两种类型:对象和数组
这里使用Gson为例:
Gson是一个Java序列化/反序列化库,能够很方便的处理JSON格式字符串。Gson有两个常用方法:toJson()
和fromJson()
,通过字面意思就很好理解
在使用之前,需要引入依赖:
implementation 'com.google.code.gson:gson:2.8.6'
下面我们以Phone
类为例:
package com.example.serializationdemo;
public class Phone {
private String name;
private int price;
public Phone(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Phone{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
Gson gson = new Gson();
Phone phone = new Phone("Android", 1000);
String json = gson.toJson(phone);
仅需一行代码就能把对象转成Json格式的字符串
{"name":"Android","price":1000}
这里为了方便查看,我们可以创建一个临时文件,选择JSON
,用于查看Json字符串

把刚刚的字符串粘贴到这,再用代码格式化查看就行了
{
"name": "Android",
"price": 1000
}
当然我们也可以把Json格式的字符串转成对象
Gson gson = new Gson();
String json = "`{\"name\":\"Android\",\"price\":1000}";
Phone phone = gson.fromJson(json, Phone.class);
上面都是单个对象,下面以数组为例
[
{
"name": "Android",
"price": 1000
},
{
"name": "Android",
"price": 1000
}
]
可以看到数组是用一对[]
包裹,中间每一对{}
代表一个对象,同理反过来也是一样的
Gson gson = new Gson();
String json = "[{\"name\":\"Android\",\"price\":1000},{\"name\":\"Android\",\"price\":1000}]";
Phone[] phones = gson.fromJson(json, Phone[].class);
当然也可以转换成列表:List<Phone> list = Arrays.asList(phones);
那么如果直接把列表转换成Json字符串以及直接把Json字符串转成列表呢?
Gson gson = new Gson();
Phone phone = new Phone("Android", 1000);
Phone phone1 = new Phone("Android", 1000);
List<Phone> list = new ArrayList<>();
list.add(phone);
list.add(phone1);
String json = gson.toJson(list);
可以看到列表转换成Json字符串也是能够实现的,但是反过来就不行了

但是是有办法解决的,在我们使用fromJson()
时,可以看到有以下参数列表:

所以我们可以使用Type
类来实现
Gson gson = new Gson();
String json = "[{\"name\":\"Android\",\"price\":1000},{\"name\":\"Android\",\"price\":1000}]";
Type type = new TypeToken<List<Phone>>() {}.getType();
List<Phone> list = gson.fromJson(json, type);
可以看到Json字符串转换成了对应的列表
关于序列化的使用差不多就这些了