Serialización Serializable y Parcelable

prefacio

Hay dos métodos de serialización de uso común en Android: Serializable y Parcelable. Entre ellos, Serializable es un método de serialización de objetos común en Java, y estará más inclinado a implementar la interfaz Parcelable en la operación de memoria real de Android.

1. Serialización y deserialización

Publicación por entregas

Dado que los objetos en la memoria son temporales y no se pueden almacenar durante mucho tiempo, para mantener el estado del objeto, es necesario escribir el objeto en el disco u otro medio.Este proceso se denomina serialización.

deserialización

es la operación inversa de la serialización.

En pocas palabras, la serialización se refiere al proceso de almacenar el estado de una instancia de objeto en un medio de almacenamiento (disco u otro medio). En este proceso, los campos públicos y privados del objeto y el nombre de la clase (incluido el ensamblado donde se encuentra la clase) se convierten en un flujo de bytes y luego el flujo de bytes se escribe en el flujo de datos. Cuando el objeto se deserialice posteriormente, se creará una copia exacta del objeto original.

2. Escenarios de aplicaciones de serialización

Existen principalmente las siguientes situaciones (pero no limitadas a las siguientes situaciones)
1) Los objetos en la memoria se escriben en el disco duro;
2) Transmisión de datos (como Intent, Binder)

3. Proceso de serialización

Para que un objeto implemente operaciones de serialización, la clase debe implementar la interfaz Serializable o la interfaz Parcelable. La interfaz Serializable es una clase de serialización abstracta en Java, y la interfaz Parcelable es una interfaz de serialización única en Android. En algunos casos, la serialización implementada por la interfaz Parcelable es más eficiente.

1. Serializable

Simplemente implemente la interfaz Serializable en la declaración de clase. Se recomienda declarar activamente el ID de serialización. El ID de identificación se puede generar automáticamente, y la declaración activa es solo para una mayor garantía de deserialización normal.

El ID de identificación de serialización utiliza la clase de serialización de identificación. Solo cuando la identificación de serialización es coherente, se puede deserializar normalmente. Los ID serializados y deserializados deben ser los mismos para que la operación de serialización se realice correctamente.

  1. Si no especifica manualmente el valor de serialVersionUID, el compilador calculará el valor hash como el UID basado en la estructura de clases actual
  2. Si el valor de serialVersionUID no se especifica manualmente, la deserialización es un cambio en la clase actual y el valor hash calculado será incoherente, lo que hará que la deserialización actual informe un error.
  3. Si la estructura de clases sufre cambios no convencionales, como modificar el nombre de clase, modificar el tipo de variable miembro, incluso si la verificación de UID pasa en este momento, la deserialización informará un error y no se podrá restaurar un nuevo tipo de objeto estructural.

Código de muestra

// 构造对象
        User user = new User();
        user.setId(1000);
        user.setName("张三");

        // 把对象序列化到文件
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/serializable/user.txt"));
        oos.writeObject(user);
        oos.close();

        // 反序列化到内存
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/serializable/user.txt"));
        User userBack = (User) ois.readObject();
        System.out.println("read serializable user:id=" + userBack.getId() + ", name=" + userBack.getName());
        ois.close();

Solo se pueden usar ObjectOutStream y ObjectInputStream para implementar la serialización y deserialización de objetos.

El objeto deserializado se creó recientemente, no es el mismo que el objeto original.

2. Parcelable

Parcelable es una serialización específica de Android, que es ligeramente mejor que Serializable en términos de memoria y tiene una sobrecarga menor.

public class User implements Parcelable {

    public int id;
    public String name;
    public User friend;

    /**
     * 当前对象的内容描述,一般返回0即可
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 将当前对象写入序列化结构中
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeString(this.name);
        dest.writeParcelable(this.friend, 0);
    }

    public NewClient() {}

    /**
     * 从序列化后的对象中创建原始对象
     */
    protected NewClient(Parcel in) {
        this.id = in.readInt();
        this.name = in.readString();
       //friend是另一个序列化对象,此方法序列需要传递当前线程的上下文类加载器,否则会报无法找到类的错误
       this.friend=in.readParcelable(Thread.currentThread().getContextClassLoader());
    }

    /**
     * public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。
     * 重写接口中的两个方法:
     * createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,
     * newArray(int size) 创建一个类型为T,长度为size的数组,供外部类反序列化本类数组使用。
     */
    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        /**
         * 从序列化后的对象中创建原始对象
         */
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        /**
         * 创建指定长度的原始对象数组
         */
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

De hecho, los objetos Parcelable deben usarse al pasar datos de tipos complejos (como datos de tipos de referencia personalizados) a través de Intents. A continuación, se muestran algunos métodos de operación de Intents en objetos Parcelable en aplicaciones diarias. Los tipos de referencia deben implementar la interfaz Parcelable para ser pasado a través de Intents, y básico El tipo de datos y el tipo String se pueden pasar directamente a través del Intent y el Intent mismo también implementa la interfaz Parcelable, por lo que se puede transferir fácilmente entre componentes.

Cuatro, la diferencia entre los dos.

1. Date cuenta de la diferencia

Serializable solo necesita implementar la interfaz Serializable. Parcelable necesita implementar Parcelable, y se debe agregar una variable miembro estática CREATOR. Esta variable necesita implementar la interfaz Creator e implementar métodos abstractos para leer y escribir.

2. La intención de diseño original de los dos

Serializable es principalmente para serializar objetos en archivos locales, bases de datos, flujos de red, etc.

Parcelable se debe principalmente a que la transferencia de datos en Android se realiza principalmente en el entorno de la memoria, por lo que la aparición de Parcelable es para cumplir con la transferencia eficiente y de bajo costo de datos en la memoria.

3. Escenarios de aplicación

Parcelable lee y escribe directamente en la memoria. Sabemos que la velocidad de lectura y escritura de la memoria es definitivamente más rápida que la del disco duro, por lo que el rendimiento del método de serialización Parcelable es mucho mejor que el del método Serializable. Por lo tanto, se recomienda que las aplicaciones de Android utilicen Parcelable al transferir datos entre memorias, como la transferencia de datos entre actividades y la transferencia de datos AIDL.

Serializable usa IO para leer y escribir para almacenar en el disco duro. El proceso de serialización utiliza tecnología de reflexión y los objetos temporales se generan durante el proceso, lo que tiene la ventaja de tener menos código. Se recomienda elegir Serializable al serializar objetos en configuraciones de almacenamiento o transferir objetos a través de la red después de la serialización.

Supongo que te gusta

Origin blog.csdn.net/cat_is_so_cute/article/details/123475270
Recomendado
Clasificación