Android面试回忆录:Serializable 都这么牛逼了,还要Parcelable有何用?

话说最近公司在招聘一批至少 5 年开发经验的 Android 开发工程师,我也是忙开了花,激动得不行呀。虽说我面试过的技术开发至少 50 人以上,但这还是第一次开始面试 Android,此时犹如大姑娘上轿,还真是头一回呀!

所以非常非常非常用心地准备了良久,然后满怀激动地开始了我的 Android 面试官角色。

无奈,面试后的感觉,均是开发效率听起来很牛逼,第三方 API 用起来非常顺手,但问到基础,就拿我面试系列的题去问,没一个答得上的,甚至是循循善诱,都没法好好回答。

面试场景

Android 开发中对两个 Activity 之前传递数据,应该很熟悉吧?

嗯,当然没问题。一般采用 Intent.putXXX() 就可以实现各种轻量级数据的传递。

那对于自定义的 Object 呢?

直接使用 Bundle 的 putSerializable() 即可。需要把对象实现 Serializable 接口,最后使用 Intent.putExtras(Bundle) 把数据放进 Intent 即可。

除了这种方式,还有其它方式吗?和这种方式有什么区别呢?

我知道还有 Bundle.putParcelable() ,不过我们平时基本都只用 Serializable 方式。

为什么不用 Parcelable 方式呢?它们有什么不同呢?

因为简单呀,Serializable 方式只需要实现接口一句代码就好了,Parcelable 我记得有很多代码。对于它们的区别嘛,em......额......嗯.......

正文

上面的场景,实际上就是在我近期发生的。作为一个简历上 09 年入行的大龄 Android 程序员,我非常肯定他的开发能力和解决问题的能力,在这方面肯定甩我很多条街,不过至少在我问的问题上让我有点大跌眼镜,问到自定义 View 的绘制顺序,直接回答不知道。问到 LaunchMode,支支吾吾,不清楚。实际上不由得让我们思考,到底是怎么了,难道现在对于这么多的程序猿,写出符合需求的代码就变得这么重要了么?还好,当下还有很多坚持在一线,努力把基础带给大家的大神,比如,扔物线朱凯,还有非常非常多的伙伴们。

大多数人可能都知道,Serializable 和 Parcelable 方式最大的区别是效率上的差异,而且对于小数据,其实差异并不是很大,这些差别其实用户层面是并不容易发现的。但这并不代表着,我们的开发就可以忽视这几十毫秒甚至是几毫秒的差距。

Serializable 和 Parcelable 的区别

可以肯定的是,两者都是支持序列化和反序列化的操作。

两者最大的区别在于 存储媒介的不同,Serializable 使用 I/O 读写存储在硬盘上,而 Parcelable 是直接 在内存中读写。很明显,内存的读写速度通常大于 IO 读写,所以在 Android 中传递数据优先选择 Parcelable。

Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作, Parcelable 自已实现封送和解封(marshalled &unmarshalled)操作不需要用反射,数据也存放在 Native 内存中,效率要快很多。

有人直接比较过两个的效率差别

我们可以来看看分别怎么写?

  • Serializable 「简单易用」一直都是它的代名词
1public class TestSerializable implements Serializable { 2 String msg; 3 4 List<ItemBean> datas; 5 6 public static class ItemBean implements Serializable{ 7 String name; 8 } 9}
  • Parcelable 速度至上
1public class TestParcelable implements Parcelable { 2 String msg; 3 4 @Override 5 public int describeContents() { 6 return 0; 7 } 8 9 @Override 10 public void writeToParcel(Parcel dest, int flags) { 11 dest.writeString(this.msg); 12 } 13 14 TestParcelable(String msg) { 15 this.msg = msg; 16 } 17 18 private TestParcelable(Parcel in) { 19 this.msg = in.readString(); 20 } 21 22 public static final Creator<TestParcelable> CREATOR = new Creator<TestParcelable>() { 23 @Override 24 public TestParcelable createFromParcel(Parcel source) { 25 return new TestParcelable(source); 26 } 27 28 @Override 29 public TestParcelable[] newArray(int size) { 30 return new TestParcelable[size]; 31 } 32 }; 33}

很明显,Parcelable 实现起来并不容易,它有成吨的模板代码,这使得对象变得难以阅读和维护。但如果你真的想成为一个优秀的 Android 开发工程师,你可能就得多在 Parcelable 上花点时间了。

在两个 Activity 之间传递对象还需要注意什么呢?

对象的大小,对象的大小,对象的大小!!!

重要的事情说三遍,一定要注意对象的大小。Intent 中的 Bundle 是使用 Binder 机制进行数据传送的。能使用的 Binder 的缓冲区是有大小限制的(有些手机是 2 M),而一个进程默认有 16 个 Binder 线程,所以一个线程能占用的缓冲区就更小了( 有人以前做过测试,大约一个线程可以占用 128 KB)。所以当你看到 The Binder transaction failed because it was too large 这类 TransactionTooLargeException 异常时,你应该知道怎么解决了。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )