博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[架构基本功]Parcelable序列化
阅读量:6148 次
发布时间:2019-06-21

本文共 3301 字,大约阅读时间需要 11 分钟。

近来在使用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
childlist; protected Person(Parcel in) { name = in.readString(); age = in.readInt(); childlist = in.createTypedArrayList(Person.CREATOR); } public static final Creator
CREATOR = new Creator
() { @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 childlist如果包含了当前的Person对象,序列化的时候,就会导致循环引用,一直序列化直到栈溢出,所以这里需要非常小心。有些时候为了代码抽象方便,很可能就会因此忽视了一些问题。

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

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

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

public abstract class Person implements Parcelable {    public String name;    public int age;    public List
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
CREATOR = new Creator
() { @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,也可以扫码进群。我在这里期待你们的加入!!!

转载地址:http://feqya.baihongyu.com/

你可能感兴趣的文章
禁用ViewState
查看>>
Android图片压缩(质量压缩和尺寸压缩)
查看>>
nilfs (a continuent snapshot file system) used with PostgreSQL
查看>>
【SICP练习】150 练习4.6
查看>>
HTTP缓存应用
查看>>
KubeEdge向左,K3S向右
查看>>
DTCC2013:基于网络监听数据库安全审计
查看>>
CCNA考试要点大搜集(二)
查看>>
ajax查询数据库时数据无法更新的问题
查看>>
Kickstart 无人职守安装,终于搞定了。
查看>>
linux开源万岁
查看>>
linux/CentOS6忘记root密码解决办法
查看>>
25个常用的Linux iptables规则
查看>>
集中管理系统--puppet
查看>>
分布式事务最终一致性常用方案
查看>>
Exchange 2013 PowerShell配置文件
查看>>
JavaAPI详解系列(1):String类(1)
查看>>
HTML条件注释判断IE<!--[if IE]><!--[if lt IE 9]>
查看>>
发布和逸出-构造过程中使this引用逸出
查看>>
Oracle执行计划发生过变化的SQL语句脚本
查看>>