[架构基本功]Parcelable序列化

作者: CangWang | 来源:发表于2019-04-30 09:25 被阅读103次
Android组件化架构

近来在使用Android序列化的时候遇到一些问题所以这里记录一下。

什么时候使用序列化?

Android中实现序列化有两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。实现Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,在一般的时候推荐用这种方法提高性能。

Parcelable和Serializable的区别

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable,除了以下介绍的坑问题。

2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。

1.但是会有特殊的时候,例如以下代码有什么问题?

public class Person implements Parcelable {
    public String name;
    public int age;
    public List<Person> childlist;

    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
        childlist = in.createTypedArrayList(Person.CREATOR);
    }

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

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

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

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

估计一眼看不出有什么问题,问题就在于如果List<Person> childlist如果包含了当前的Person对象,序列化的时候,就会导致循环引用,一直序列化直到栈溢出,所以这里需要非常小心。有些时候为了代码抽象方便,很可能就会因此忽视了一些问题。

2.ParcelIn和writeToParcel的读和写的顺序需要是一致的,不然序列化会出错。

3.每次新加入属性,需要记得手动再次生成Parceble相应的方法。AS编译器生成是最稳的,别作死自己写。

4.抽象继承传递问题。
Person抽象类方法

public abstract class Person implements Parcelable {
    public String name;
    public int age;
    public List<Person> childlist;

    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
        childlist = in.createTypedArrayList(Person.CREATOR);
        job = in.readString();
    }

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

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

    abstract String getJob();

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

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

Father实类

public class Father extends Person{
    public String job;

    protected Father(Parcel in) {
        super(in);
    }

    @Override
    String getJob() {
        return "soft engineer";
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest,flags);
    }
}

这样一开始看没什么问题,可以正常传递。但是使用intent传递的时候,经过序列化后很有可能会数据丢失。因为抽象方法导致,某些数据序列化失败。
这种场景有两种解决方法
1.使用Serializable来序列化
2.将序列化操作移动到父类进行。
当然如果你有更好的写法可以联系我吧。

我建立了一个关于Android架构学习的群,里面可以进一步进行组件化学习和架构思想的的交流。

群号是316556016,也可以扫码进群。我在这里期待你们的加入!!!

Android组件化架构 组件化架构2群

相关文章

  • [架构基本功]Parcelable序列化

    近来在使用Android序列化的时候遇到一些问题所以这里记录一下。 什么时候使用序列化? Android中实现序列...

  • 序列化Serializable和Parcelable

    序列化主要有两种方式:Serializable,Parcelable;区别:内存的序列化Parcelable(直接...

  • AS插件的使用

    Parcelable方式的自动序列化 Android Parcelable code generator实现...

  • Android序列化

    提问:什么是序列化?为什么要序列化?为什么要使用Parcelable?Parcelable与Serializabl...

  • 序列化

    Parcelable Parcelable是一个接口,只要实现这个接口,该类的对象就可以实现序列化。序列化:由wr...

  • Android - Serializable和Parcelabl

    目录 Parcelable与Serializable的性能比较 传递消息 插件自动生成Parcelable序列化 ...

  • Parcelable使用记录

    Parcelable是Android为我们提供的序列化的接口,Parcelable相对于Serializable的...

  • Parcelable&Serializable序列化使用

    Parcelable序列化接口使用## 首先先实现Parcelable接口 以下是JavaBean的代码片段 Se...

  • Java序列化

    Android序列化 目标 为什么序列化 序列化的定义 Serializable的使用和原理 Parcelable...

  • Android序列化简析

    目录1、序列化与反序列化概念2、序列化用途3、Serializable实现序列化4、 Parcelable实现序列...

网友评论

    本文标题:[架构基本功]Parcelable序列化

    本文链接:https://www.haomeiwen.com/subject/ajopnqtx.html