likes
comments
collection
share

AndroidCoder 浅谈序列化

作者站长头像
站长
· 阅读数 36

前言

在Android日常开发中,进行数据传输或者存储本地数据操作时,离不开的操作就是将对象数据序列化,就是将对象转化为字节序列传输,再进行反序列化操作存储到本地或者网络上。Android中还提供了针对移动平台优化过的序列化接口Parcelable,本文就来介绍一下它们!

概览

AndroidCoder 浅谈序列化

1. 定义与相关概念

1.1 序列化

数据结构或对象转换成二进制的过程,就是将数据结构或对象转换成可以存储或者传输的数据格式的过程。 目的:主要用于网络传输,数据持久化,一般序列化也称为编码(Encode)

1.2 反序列化

二进制串转换成数据结构或对象的过程,就是序列化生成的二进制串数据被还原成数据结构或对象的过程。 目的:主要用于从网络,磁盘上读取字节数组还原成原始对象,一般反序列化也称为解码 (Decode)

2. 常见的序列化接口

2.1 Android中提供的 Parceable

Parcelable 是 Android SDK 为提供的序列化接口,它是基于内存的,由于内存读写速度高于硬盘,在 Android 中的跨进程对象的传输一般使用 Parcelable

Parcelable 相对于 Serializable 的使用复杂一些,但是 Parcelable 的效率比 Serializable 也高很多: 因为是Android定制化的接口,只能在Android项目中使用

public class Course implements Parcelable {
    private String name; //属性 name
    ...
    
    public Course(Parcel in) {
        this.name = in.readString();
        ...
    }
    
    ...
    
    // 反序列化,将 Parcel 对象转换为 Parcelable
    public static final Creator<Course> CREATOR = new Creator<Course>() {
        //反序列化的方法,将Parcel还原成Java对象
        @Override
        public Course createFromParcel(Parcel in) {
            return new Course(in);
        }
        //提供给外部类反序列化这个数组使用。
        @Override
        public Course[] newArray(int size) {
            return new Course[size];
        }
    };
    
    @Override
    public int describeContents() {
        return 0;
    }
    
    // 序列化,将对象转换成一个 Parcel 对象
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        ...
    }
}

从上面示例来看,它的用法比 Serializable 复杂太多了,不过好在现在编辑器的智能化处理,并不用手动输入这些实现代码,全部可以快速生成,也非常的方便。内部的主要几个方法已经注释标明

2.2 Java中提供的 Serializable

Serializable 是 Java 提供的序列化接口,代码很简单:

// Serializable 接口
public interface Serializable {
    ...
}

// 用法:数据类实现Serializable接口即可
public class Person implements Serializable {
    // 生成唯一的序列化ID
    private static final long serialVersionUID = 791165065084633143L;
    ...
    // 用 transient 关键字标记的成员变量不参与序列化
    private transient Date createTime;
    // 静态成员变量属于类而不属于对象,不参与序列化
    private static SimpleDateFormat dateFormat = new SimpleDateFormat();
    ...
}

在使用Serializable时,有几个特点:

  • 一个类要实现序列化和反序列化,那它必要实现Serializable接口
  • 一个实现序列化的类,它的子类也是可以序列化的
  • 用 transient 关键字标记的成员变量不参与序列化
  • 静态成员变量不参与序列化

serialVersionUID是唯一生成的,序列化的类要正确无误反序列化,就是通过对比它的唯一性。

3序列化接口性能比较

3.1 Parcelable 接口性能分析

Parcelable 是Android平台优化Java中的Serializable,适用于移动端轻量级的序列化API,它内部以 IBinder 作为信息载体,在内存上开销比较小。

所以在内存之间进行数据传递时,推荐使用 Parcelable,但是 Parcelable 对数据进行持久化或者网络传输时操作复杂,这个时候推荐使用 Serializable

3.2 Serializable性能分析

Serializable 是 Java API 中提供的序列化接口,平常开发中使用它较为简单,AClass implements Serializable 自动生成唯一的ID即可。由于 Serializable序列化过程使用的是反射机制,会产生大量临时变量,GC过于频繁,这些会导致开销增大。它主要通过IO流的形式进行数据的读写。

所以在操作大量复杂数据时,不建议使用Serializable

总结

今天主要讲解了两种序列化接口:ParcelableSerializable,通过示例展示了不同的使用方式,在日常应用开发中,根据实际数据传输场景选取合适的序列化方式,这对程序性能优化有积极作用。

转载自:https://juejin.cn/post/7133112211307757575
评论
请登录