Android面试一天一题(9 Day)

作者: goeasyway | 来源:发表于2016-06-06 11:27 被阅读8950次

面试题:两个Activity之间如何传递参数?

在Android应用中,Activity占有极其重要的地位,Activity间的跳转更是加常便饭。即然跳转(界面切换)不可避免,那么在两个Activity之间传递参数就是一个常见的需求。大多数时候,我们也就传递一些简单的int,String类型的数据,实际中也有看到传递List和Bitmap的。

那么我们先回答这个题,如何传递参数:

使用Intent的Bundle协带参数,就是我们常用的Intent.putExtra方法。

做为面试官,紧接着可以问:除了传递基本类型外,如何传递自定义的对象呢?

这个问题就是想引出Android的Parcelable。一般很多面试者都有用过传递实现了Serializable接口的自定义对象的经验,因为这个很简单,加句代码就搞定了。而Parcelable的实现要多一些代码,典型的写法如下:

public class MyParcelable implements Parcelable {
     private int mData;

     public int describeContents() {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mData);
     }

     public static final Parcelable.Creator<MyParcelable> CREATOR
             = new Parcelable.Creator<MyParcelable>() {
         public MyParcelable createFromParcel(Parcel in) {
             return new MyParcelable(in);
         }

         public MyParcelable[] newArray(int size) {
             return new MyParcelable[size];
         }
     };
     
     private MyParcelable(Parcel in) {
         mData = in.readInt();
     }
}

那我们为什么要考察对方会不会用Parcelable呢?先看一下这Parcelable和Serializable的区别:

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

有人比较过它们两个的效率差别:

不同类型的数据不一定差据这么大,但却很直观的展示了Pacelable比Serializable高效。

有时面试官还可以追问一下:Parcelable和Parcle这两者之间的关系。

Parcelable 接口定义在封送/解封送过程中混合和分解对象的契约。Parcelable接口的底层是Parcel容器对象。Parcel类是一种最快的序列化/反序列化机制,专为Android中的进程间通信而设计。该类提供了一些方法来将成员容纳到容器中,以及从容器展开成员。

现在我们知道了如何传递自定义的对象,那么在两个Activity之前传递对象还要注意什么呢?

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

因此,使用Intent在Activity之间传递List和Bitmap对象是有风险的。

面试官可以就这个问题再展开,看面试者如何解决。

还有一个要注意的:因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化。之前我有过一次,将Android的PackageInfo进行持久化到数据库,结果用户升级Android系统后,再从数据库解封PackageInfo时应用就Crash了。

结论

对于初级的程序员来说,只要能抓住老鼠,白猫或者黑猫甚至是小狗都是没有区别的。但对于应用的流畅和体验来说,100毫秒和1000毫秒是有很大区别的。很多程序员眼里无关紧要的差别,最终在用户那儿会被几倍十几倍的放大,老板也会因为用户的投述而斥责你。因为总会有用户在用性能很差的手机,总有用户手机的使用情况很复杂(内存紧张,网络复杂等等),总有用户本人就很奇葩不会按你指定的套路出拳!当你鄙视老板不懂代码的艺术时,老板也会鄙视你不懂用户不懂细节的重要性,活该你一辈子做程序员。

所以,在能使用的Parcelable的地方,请不要贪图简便直接Serializable,实在懒的话也可以试试用插件自动生成Pracelabel的模板代码:android-parcelable-intellij-plugin

相关文章

  • Android面试一天一题-goeasyway

    以下文章作者:goeasyway Android面试一天一题(1 Day) Android面试一天一题(2 Day...

  • MS(1):Android之架构篇

    一、架构相关 1、MVC,MVP,MVVM MS思考:Android面试一天一题(Day 33:Android开发...

  • 面试题

    最全的BAT大厂面试题整理答案Android面试一天一题(Day 37:一套高级工程师的面试题)Android面试...

  • MS(2):Android之基础知识篇

    二、组件 1、Activity----------1 MS思考:Android面试一天一题(3 Day):Acti...

  • MS(7):非技术问题篇

    一、GM问非技术问题汇总 MS思考:Android面试一天一题(Day 34:常去的Android相关站点) 说下...

  • MS(3):Android之机制原理篇

    五、重点机制原理 1、Handler机制 MS思考:Android面试一天一题(8 Day):Handler相关分...

  • MS(5):android之进阶篇

    七、自定义View MS思考:Android面试一天一题(Day 30:老外的自定义View面试题)MS思考:老外...

  • android Service 一些思考

    看了Android面试一天一题(1 Day),对Service 的一些总结与思考 作者原文章链接: http://...

  • MS(6):Java篇

    MS思考:Android面试一天一题(7 Day):Java相关 1.Switch能否用string做参数? 在J...

  • 读goeasyway文章有感

    今天在地铁上读goeasyway的文章《Android面试一天一题(Day 39:写博客很重要吗?)》,很有感触,...

网友评论

  • 653d1ebd6d6d:那activity之间怎么传递大容量的对象呢?楼主给个答案呗!谢谢!
    Jdqm:全局变量也是一个方案
    在代码下成长:可以考虑下文件
  • 瞎子摸牛:Parcelable与Serializable的性能比较

    首先Parcelable的性能要强于Serializable的原因我需要简单的阐述一下

    1). 在内存的使用中,前者在性能方面要强于后者

    2). 后者在序列化操作的时候会产生大量的临时变量,(原因是使用了反射机制)从而导致GC的频繁调用,因此在性能上会稍微逊色

    3). Parcelable是以Ibinder作为信息载体的.在内存上的开销比较小,因此在内存之间进行数据传递的时候,Android推荐使用Parcelable,既然是内存方面比价有优势,那么自然就要优先选择.

    4). 在读写数据的时候,Parcelable是在内存中直接进行读写,而Serializable是通过使用IO流的形式将数据读写入在硬盘上.

    但是:虽然Parcelable的性能要强于Serializable,但是仍然有特殊的情况需要使用Serializable,而不去使用Parcelable,因为Parcelable无法将数据进行持久化,因此在将数据保存在磁盘的时候,仍然需要使用后者,因为前者无法很好的将数据进行持久化.(原因是在不同的Android版本当中,Parcelable可能会不同,因此数据的持久化方面仍然是使用Serializable)
  • 9b4f2400ea72:Parcelable 接口定义在封送/解封送过程中混合和分解对象的契约。
    契约可能翻译成协议更好 = =。
  • 丘处机:把对象转成json,传递到第二个activity再转回来可以吗。。。效率呢。。
    13号大王:可以,但是有局限性。首先,对象的类型必须是POJO;其次复杂类型转换成JSON String的大小,会远远超过对象原本的大小,得不偿失。
  • 望北8261:我用Application传递数据的,有问题么
    岁月留痕:不是说不建议用 Application 传递数据吗 ,前面看文档说如果应用长期在后台被销毁后 ,application 的值会被清空
    望北8261: @Overried 对哦,没考虑到这个。不过一般情况下都是一个进程
    trycatchx:@追意狂人 不同进程肯定有问题:relieved:
  • ElvenShi:我一般习惯在AS上用插件生成Parcelable序列化代码,实体类字段少还好,太多的话手写太浪费时间了。之前没有用插件之前,如果字段太多就懒得实现Parcelable了,直接实现Serializable。
  • 3c29994c814c:个人觉得android涉及面太广,很难对这么多概念都有深入的分析并能时间的记住,对于android开发来说最核心的技能在于架构以及解决问题的能力,短时间内透彻掌握目标知识并熟练应用是衡量一个android开发工程师的关键。
  • 关山明月:简直不能再帅了,还真没发现Pacelable比Serializable 好这么多,以前一直用Serializable ,赞! :+1:
  • 会疼的小石头:群主摸摸哒
  • EMG: :+1: 细节决定是不是高手!深有感触呀
  • 工程师milter:binder不是用来跨进程通信的吗?为什么activity间传递bundle要使用binder,一个进程默认有16个binder线程是什么意思,请大神推荐些相关资料
    工程师milter:@野生ChaoS 明白,谢谢!
    工程师milter:明白了,第二个问题是怎么回事呢?看了大神的文章,感觉自己没学过Android一样,惶恐啊
    goeasyway:很多Activity并不是在一个进程中,比如你从自己的应用通过Intent打开一个发Email的Activity,你要往这样Activity传一些诸如收件人、主题等信息吧。这样一想Intent的传递肯定就是要跨进程的了。Binder的问题一两句难说清楚,之后我专门写一篇关于这个问题的。
  • one_cup:想到一个问题,问什么同样都是序列化,Pacelable要比Serializable的性能高这么多,猜测Serializable在执行序列化的时候是不是把这个类中的所有内容都序列化了?包括空格?和其他的一些没有意义的东西,而Pacelable在序列化的时候是由程序员来决定要序列化哪些属性(方法???)仅仅是想要实现序列化的,其他的都不管,可怎样才能验证下这个结论那?Serializable能通过反序列化来获得XML可Pacelable应该怎么处理? :scream: :scream:
    我不是死胖子:@__Berial___ 第一句非常对!!Serializable本身是为了持久化存储而设计的java.io里的接口, 而Parcelable是android 为了进程间通信设计的, 是为了传递.
    13号大王:Parcelable没有序列化,而是将需要需要保存的数据write到一个Parcel对象,然后还原的时候再从Parcel对象中读取出来,是基于字节以及字节地址的,效率高一些。而Serializable的序列化与还原,是基于反射reflection的,效率较低。
    __Berial___:@one_cup 我觉得 Pacelable 和 Serializable 序列化的作用是不同的,Pacelable 是为了“传递”,而 Serializable 是为了“储存”。另外 Serializable 之所以慢,是由于为了读取对象中的成员变量而使用的大量的反射,而 Pacelable 的读写都是自己实现的。还有 Serializable 也是可以自己设置不想要序列化的属性的,只需要在该变量前加一个 transient 关键字(static 标记的属性也是不能序列化的,但是 static final 的可以)。
  • 0af700ea3d10:写的不错
  • 小李子_忽略下滑线后面的:感谢 支持楼主持续更新
  • 老衲法号能吃:群主,我要给你生猴子。。。 :joy:
    老衲法号能吃:@goeasyway :wink:
    goeasyway:@老衲法号能吃 :scream:
  • 追逐丶:学习了😊
  • timloong:简直不要太帅啦~~😄 最近在准备面试,看一些基本的东西,所以你的每篇都会收藏~ Parcellable用过,但没对比过Serializable的性能,真👍

本文标题:Android面试一天一题(9 Day)

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