文档章节

Parcelable vs Serializable

iuKa
 iuKa
发布于 2015/05/18 22:59
字数 1045
阅读 44
收藏 0

###Parcelable vs Serializable

在一开始学习Android的时候,我们就知道了不能在Activity和Fragment之间直接传递对象,必须使用Intent或者Bundle。 查看api后,我们发现有两个选择,让我们的对象要么实现Parcelable,要么实现Serializable。作为Java开发者,我们都知道Serializable机制,那么为什么还需要Parcelable呢? 要接解答这个问题,先来看两个列子

####Serializable-简洁之至

// access modifiers, accessors and constructors omitted for brevity
public class SerializableDeveloper implements Serializable
    String name;
    int yearsOfExperience;
    List<Skill> skillSet;
    float favoriteFloat;

    static class Skill implements Serializable {
        String name;
        boolean programmingRelated;
    }
}

正如你所见到的,只需要在类和成员变量引用类实现Serializable接口就可以了,并且不需要实现任何方法。其他的事情统统交给Java去做,简洁之至。 但是Serializable的问题就是处理太慢,Java是采用反射去实现序列号操作。并且在处理序列化的时候还会生成大量的对象,导致GC频繁发生。

####Parcelable-速度之王

// access modifiers, accessors and regular constructors ommited for brevity
class ParcelableDeveloper implements Parcelable {
String name;
int yearsOfExperience;
List<Skill> skillSet;
float favoriteFloat;

ParcelableDeveloper(Parcel in) {
    this.name = in.readString();
    this.yearsOfExperience = in.readInt();
    this.skillSet = new ArrayList<Skill>();
    in.readTypedList(skillSet, Skill.CREATOR);
    this.favoriteFloat = in.readFloat();
}

void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(yearsOfExperience);
    dest.writeTypedList(skillSet);
    dest.writeFloat(favoriteFloat);
}

int describeContents() {
    return 0;
}


static final Parcelable.Creator<ParcelableDeveloper> CREATOR
        = new Parcelable.Creator<ParcelableDeveloper>() {

    ParcelableDeveloper createFromParcel(Parcel in) {
        return new ParcelableDeveloper(in);
    }

    ParcelableDeveloper[] newArray(int size) {
        return new ParcelableDeveloper[size];
    }
};

static class Skill implements Parcelable {
    String name;
    boolean programmingRelated;

    Skill(Parcel in) {
        this.name = in.readString();
        this.programmingRelated = (in.readInt() == 1);
    }

    @Override
    void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(programmingRelated ? 1 : 0);
    }

    static final Parcelable.Creator<Skill> CREATOR
        = new Parcelable.Creator<Skill>() {

        Skill createFromParcel(Parcel in) {
            return new Skill(in);
        }

        Skill[] newArray(int size) {
            return new Skill[size];
        }
    };

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

根据google开发人员所说,这段代码执行速度会有明显的提升。其中一个原因是,我们正在明确有关序列化过程,而不是使用反射来推断它。这里也可以看到,代码为实现这个目的做了大量的优化。 然而Parcelable也不是免费的,它需要按规则编写大量的代码模板去实现序列化过程,并且难以阅读。

####性能测试

那么问题来了,Parcelable究竟有多快?

#####测试步骤

  1. 在Activity中使用Bundle#writeToParcel(Parcel, int)方法将一个对象写入,然后再取出来来模仿对象传递的过程。
  2. 重复运行1000次
  3. 取10次平均值,为了反映不同内存使用,其他app不同cpu消耗等情况
  4. 使用上面的SerializableDeveloperParcelableDeveloper进行测试
  5. 在不同手机不行版本下运行 + LG Nexus 4 - Android 4.2.2 + Samsung Nexus 10 - Android 4.2.2 + HTC Desire Z - Android 2.3.3

#####测试结果

测试结果

Nexus 10 Serializable: 1.0004ms, Parcelable: 0.0850ms - 10.16x 提升. Nexus 4 Serializable: 1.8539ms - Parcelable: 0.1824ms - 11.80x 提升. Desire Z Serializable: 5.1224ms - Parcelable: 0.2938ms - 17.36x 提升.

结果就是这样,Parcelable至少比Serializable快10倍。而且还可以看到,即使在Nexus 10上,一个相对简单对象做一次完整的serialize/deserialize也需要1毫秒。

####结论

如果你想做一个优秀的开发者,请尽量使用Parcelable。因为Parcelable至少会快10倍而且占用更少的内存。 在大多数情况下,缓慢的Serializable也不会被特别注意到。用它也不会有多大关系,但是请记住,它是一个昂贵的操作。 如果你试着传递数以千计的Serializable对象数组或列表,处理整个过程可能需要花费超过一秒的时间。就会导致页面跳转或者横竖屏切换呆滞。

####后记

如果你看到了这里,我就会给你免费赠送一个大礼包! 手动写Parcelable实在是太麻烦了,而且大部分都是复制黏贴改动。网上的工具类原理也是使用apt生成代码,然后反射执行,对效率还是稍稍有点影响。 幸运的是,现在AndroidStudio已经有了辅助插件——Android Parcelable Code Generator。使用这款插件可以方便的自动生成Parcelable代码。

安装方法:

  1. 下载安装包
  2. 打开IntelliJ或者Android Studio
  3. Settings -> Preferences -> Plugins -> Install plugin from disk....
  4. 选择下载的安装包

在win中按下alt+Insert,mac按下command+N。效果如下: 生成代码

参考资料 http://www.developerphil.com/parcelable-vs-serializable/ https://plugins.jetbrains.com/plugin/7332?pr=androidstudio https://github.com/mcharmas/android-parcelable-intellij-plugin

© 著作权归作者所有

iuKa
粉丝 12
博文 11
码字总数 9266
作品 0
杭州
程序员
私信 提问
Android Intent (2) Serializable vs Parcelable

Android 主要是通过Intent来实现组件之间的相互调用,同时还可以传递附加的数据。这些数据主要是存储在Bundle之中(当调用Intent.putExtras(Bundle)时,Android会复制Bundle中的数据,而不是...

风荷举
2013/11/09
402
2
Kotlin , Parcelable 与 Serializable

注意:本文的示例,用的是Kotlin,代码逻辑模型是MVVM Parcelable 与 Serializable,是数据序列化的2种方式,他们的区别有2个: 其一,Parcelable性能上优于Serializable。Serializable是通过...

Sn__
2018/04/23
0
0
Android Parcelable接口

1、实现Parcelable就是为了进行序列化,那么,为什么要序列化? 1)永久性保存对象,保存对象的字节序列到本地文件中; 2)通过序列化对象在网络中传递对象; 3)通过序列化在进程间传递对象...

SRain215
2016/04/27
34
0
Android中Parcelable接口用法

Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel。 Classes implementing the Parcelable interface must also have a static field ......

AlexMahoneFBI
2015/03/09
107
0
Android Parcelable和Serializable的区别

Android Parcelable和Serializable的区别 本文主要介绍Parcelable和Serializable的作用、效率、区别及选择,关于Serializable的介绍见Java 序列化的高级认识。 1、作用 Serializable的作用是...

LiSteven
2013/01/15
95
0

没有更多内容

加载失败,请刷新页面

加载更多

MVC Linux下开发及部署

linux使用的是 Ubuntu 64 位 18.04.2 LTS 首先复制C:\Program Files (x86)\Embarcadero\Studio\20.0\PAServer 下 LinuxPAServer20.0.tar.gz 到 linux 目录下 运行链接编译程序 delphi环境配置......

苏兴迎
今天
9
0
3.控件及其属性

1.文本 2.按钮

横着走的螃蟹
今天
7
0
安装Genymotion模拟器慢的解决方案

第一步点击下载, C:\Users\Administrator\AppData\Local\Genymobile\genymotion.log 中搜索 ova 会发现这个文件 使用迅雷下载即可. 在 虚拟机中导入这个.ova 文件 即可安装...

chenhongjiang
今天
5
0
4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)

你好,我是彤哥,本篇是netty系列的第四篇。 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识。 简介 上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使用纯纯的N...

彤哥读源码
今天
7
0
如何把握好面试的最后一问 ?

如何把握好面试的最后一问 ? 你有没有听过这句话 “ 你还有什么问题想问我的吗? ” 如何把握好面试的最后一问 ? 要积极稳妥,切莫减分、丢分、扣分。比如,你提问的问题很傻很天真,比如你提...

编程三分钟
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部