首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

两个Activity之间传递数据全面解析

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

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

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

除了传递基本类型外,如何传递自定义的对象呢?

Activity之间传递对象,我们一般要进行序列话,进行序列化可以通过实现Serializable接口,但是这种是效率比较低的,比较高效的是实现Parcelable接口。大概如下代码

public classParcelableDemoEntityimplementsParcelable{

publicStringkey;

protectedParcelableDemoEntity(Parcelin) {

key= in.readString();

}

public static finalCreator

CREATOR=

newCreator

() {

@Override

publicParcelableDemoEntitycreateFromParcel(Parcelin) {

return newParcelableDemoEntity(in);

}

@Override

publicParcelableDemoEntity[]newArray(intsize) {

return newParcelableDemoEntity[size];

}

};

@Override

public intdescribeContents() {

return;

}

@Override

public voidwriteToParcel(Parceldest,intflags) {

dest.writeString(key);

}

}

那我们为什么要考察对方会不会用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进行数据持久化。

结论

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

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

android-parcelable-intellij-plugin

地址:https://link.jianshu.com/?t=https://github.com/mcharmas/android-parcelable-intellij-plugin

Parcelable与Serializable的性能比较

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

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

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

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

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

但是:虽然Parcelable的性能要强于Serializable,但是仍然有特殊的情况需要使用Serializable,而不去使用Parcelable,因为Parcelable无法将数据进行持久化,因此在将数据保存在磁盘的时候,仍然需要使用后者,因为前者无法很好的将数据进行持久化.(原因是在不同的Android版本当中,Parcelable可能会不同,因此数据的持久化方面仍然是使用Serializable)

Activity 传值除了 传的数据大小之外还有其他注意的吗?

Intent 传值的时候可以通过

intent.putExtra("key","value");

也可以 通过

intent.putExtras(bundle)

这两个有什么区别和优势吗

如果是放的bundle,这获取的时候也是获取bundle

getIntent().getExtras();

获取bundle之后再获取 传的value;

如果直接key,value 传值则直接去获取即可。

还有一个优势:如果Activity跳转另一个Activity之后,对应的Activity 又要把key,value传递到Fragment 或者再传到下一层的Activity,则 Bundle就一直属于封装状态,可以一级一级的传递。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180429G07W0C00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券