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

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

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

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

面试场景

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

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

那对于自定义的 Object 呢?

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

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

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

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

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

正文

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

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

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 )