Android序列化和反序列化

序列化和反序列化是什么

1.序列化是将对象持久化保存的一种方式。它会将数据转化为字节序列。
2.反序列化是将字节序列还原为数据

为什么要序列化

前面说到序列化是将数据转化为字节序列,对于字节序列有如下好处。
1.便于存储,将序列写入输出数据流中,存储到文件中
2.便于传输,字节序列可以直接用于网络传输,进程间传递对象,将可序列化对象放入Intent或Bundle中,在组建中进行传递

实现方式

两种实现方式Serializable和Parcelable.
这里需要讲解一些注意点:
1.static关键字,拥有static关键字的属性不会自动序列化,除非你writeInt,writeString等将其写出
2.transient关键字,修饰的字段属性不会被序列化,此关键字只对属性有效
3.serialVersionUID关键字,将class与serialVersionUID相联系,用于在反序列化的时候验证序列化时使用的类和加载时是否使用的是一个类,否则抛出InvalidClassException

Serializable

特点:
1.是一种标识接口(marker interface),Class直接实现Serialization接口即可.
2.利用了反射机制,序列化非常慢。

1
2
3
4
public class SerializationClass implements Serializable{
String name;
int age;
}

Parcelable

官网
特点:

  1. 不利用反射,直接显式将字段写出,速度快效率高
  2. Parcelable的数据传输依靠parcel实现,不适合进行持久化存储。

Parcelable接口会实现3个函数,和一个CREATOR(假定定义类ParcelableClass实现了Parcelable接口)

  1. protected ParcelableClass(Parcel in) :将数据从parcel读入到对象中
  2. public static final Creator CREATOR:构造器,两个方法,一个创建一个对象,另一个创建一个对象数组
  3. public int describeContents():描述Parcelable实例的排列形式,一般会返回0
  4. public void writeToParcel(Parcel dest, int flags):将数据写入parcel对象,以什么样的顺序写入就会以什么样的顺序读出。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    public class ParcelableClass implements Parcelable{
    String name;
    int age;
    Grade grade;

    public ParcelableClass(String name,int age,Grade grade){
    this.name = name;
    this.age = age;
    this.grade = grade;
    }

    protected ParcelableClass(Parcel in) {
    this.name = in.readString();
    this.age = in.readInt();
    //this.grade = in.readTypedObject(Grade.CREATOR);//API23之后可用
    this.grade = (Grade)in.readValue(Grade.class.getClassLoader());
    }

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

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

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

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

    public static class Grade implements Parcelable{
    String course;
    int grade;

    public Grade(String course,int grade){
    this.course = course;
    this.grade = grade;
    }
    protected Grade(Parcel in) {
    this.course = in.readString();
    this.grade = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(course);
    dest.writeInt(grade);
    }

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

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

    @Override
    public Grade[] newArray(int size) {
    return new Grade[size];
    }
    };
    }
    get(),set()函数。
    }

Activity之间传递:
FirstActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
ParcelableClass.Grade grade = new ParcelableClass.Grade("math", 100);
ParcelableClass parcelableClass = new ParcelableClass("chenfeng", 21,grade);
Log.e(TAG, "序列化前");
Log.e(TAG, "name:" + parcelableClass.getName());
Log.e(TAG, "age:" + parcelableClass.getAge());
Log.e(TAG, "Grade-course:" + parcelableClass.getGrade().getCourse());
Log.e(TAG, "Grade-grade:" + parcelableClass.getGrade().getGrade());
Bundle bd = new Bundle();
bd.putParcelable("pd",parcelableClass);
Intent intent = new Intent();
intent.putExtra("bd",bd);
intent.setClass(MainActivity.this,SecondActivity.class);
startActivity(intent);

SecondActivity

1
2
3
4
5
6
7
8
9
    Bundle bd = getIntent().getBundleExtra("bd");
if(bd == null) Log.e(TAG, "onCreate: bd == null");
ParcelableClass parcelableClass1 = bd.getParcelable("pd");
Log.e(TAG, "序列化后");
Log.e(TAG, "name:" + parcelableClass1.getName());
Log.e(TAG, "age:" + parcelableClass1.getAge());
Log.e(TAG, "Grade-course:" + parcelableClass1.getGrade().getCourse());
Log.e(TAG, "Grade-grade:" + parcelableClass1.getGrade().getGrade());
}

结果

参考链接:
android-parcelable-serializable,transient,serizlizationUID

不足之处请指教!
转载请注明出处@author chenfeng

-------------本文结束感谢您的阅读-------------
鼓励鼓励!