Android  Intent传递数据底层分析详细介绍

我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法。

但是不知各位有没有想过这样一个问题:ActivityB中获取到的对象跟上一个Activity中的那个对象有什么关系?

换句话说就是,我在ActivityB中通过Intent获取的对象跟ActivityA中的那个对象,有没有可能是同一个对象?

按照常理来说,博主提出一个设想后续的就是证明过程了,但是我要遗憾的告诉你,这里并非是同一个对象。(PS:废话,如果是同一个对象,那还有EventBus这些东西什么事儿 T_T)

那么问题又来了,这两个Activity都在同一个进程里面,甚至都在同一个线程里面,数据本来就是可以共享的,为什么从一个Activity传到另一个Activity之后,就不是一个对象了呢?它从什么时候变成另外的对象的呢?

不着急,且听我慢慢道来。

Intent是什么东西?

public class Intent implements Parcelable,Cloneable

上面是Intent类的完整声明,可以知道它实现了Parcelable接口。Parcelable接口是什么呢?这东西是Android上专门用来对数据进行序列化的,并且在跨进程通讯时Parceable对象是可以直接传输的。

接下来我们来看看将数据放入Intent的时,做了哪些处理。

以String为例,先看putExtra方法的代码

public Intent putExtra(String name,String value) {

if (mExtras == null) {

mExtras = new Bundle();

}

mExtras.putString(name,value);

return this;

}

很简单,就是将数据放入mExtras这个Bundle对象中,顺便说一句Bundle类也实现了Parcelable接口。继续往下跟代码

public void putString(@Nullable String key,@Nullable String value) {

unparcel();

mMap.put(key,value);

}

内部就是将数据放入一个Map中保存。到这里数据放入Intent的过程就完成了,实际上就是Intent中有一个Bundle对象,而这个Bundle对象中又有一个Map,然后数据就保存在这里。至于那个unparcel()方法与我们的分析过程无关,有兴趣的读者可以去研究一下。

然后,我们再看取数据的过程。

继续以String作为例子,看Intent中的代码

public String getStringExtra(String name) {

return mExtras == null ? null : mExtras.getString(name);

}

mExtras应该很熟悉了,这是个Bundle对象,刚刚保存数据的时候就是把数据保存在它里面的。再看它的getString方法

public String getString(@Nullable String key) {

unparcel();

final Object o = mMap.get(key);

try {

return (String) o;

} catch (ClassCastException e) {

typeWarning(key,o,"String",e);

return null;

}

}

就是直接从Map里面拿出我们之前保存的String,try语句只是在验证取出的数据是否为String类型。

那照这么分析的话,两个Activity中的对象应该就是同一个对象才对啊!!为什么又说不是同一个对象呢?

为什么不是同一个对象?

如果你在putExtra之后,马上又getExtra出来,那么你取出来的对象肯定是同一个对象,这个没错!

但是这里我们要注意两点:

1.Intent中允许保存的数据类型是有限制的,准确的说是Bundle的限制,因为实质上数据是保存在Bundle中。如果我们要保存自己定义的对象,那么我们的对象必须实现了Parcelable接口或者Serializable接口。

2.我们使用Intent的方式,基本都是在一个Activity中存入,然后从另一个Activity中取出。

那么问题很明显就出在Activity的启动过程了。详细的启动过程大家可以参考老罗的文章Activity启动过程。

这里大概说一下,首先我们的app运行在app自己的进程appProcess中,然后系统在启动的时候会启动一个系统进程systemProcess。而在Activity启动时,需要向一个叫做ActivityManagerService的系统服务去注册,这样我们的Activity才能有生命周期的回调。这个ActivityManagerService服务就运行在systemProcess中。注册完之后,再回到appProcess中,完成新Activity的启动。在这个注册过程中,我们的intent是全程参与的。

说到这里就明白了,当我们调用startActivity(intent)启动另外的Activity的时候,我们的intent已经完成了两次跨进程通信,而它里面的对象已经经历了两轮序列化和反序列化,肯定不可能是同一个对象了。

这里顺便说一个问题:为什么Serializable也可以跨进程传输?

熟悉AIDL的同学都很清楚,AIDL跨进程通信支持的数据类型是:

Java 的原生类型,如int,boolean,long,float…

String 和CharSequence

List 和 Map,List和Map 对象的元素必须是AIDL支持的数据类型

AIDL 自动生成的接口 需要导入(import)

实现android.os.Parcelable 接口的类. 需要导入(import)。

这里并不包括Serializable类型。

于是去看了源码,发现是Parcel自己对Serializable类型的对象做了兼容,可以直接写入其中。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

小编个人微信号 jb51ccc

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

android中intent放数据类型,Android Intent传递数据底层分析详细介绍相关推荐

  1. Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家

    Android  Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...

  2. Android中使用HttpURLConnection实现GET POST JSON数据与下载图片

    Android中使用HttpURLConnection实现GET POST JSON数据与下载图片 Android6.0中把Apache HTTP Client所有的包与类都标记为deprecated ...

  3. android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

    1.0 可以利用Intent吧数据传递给上一个活动,新建一个叫"hellotest01"的项目. 新建活动FirstActivity,勾选"Generate Layout ...

  4. 使用显式Intent向下一个活动传递数据

    在启动活动时传递数据的思路很简单,Intent提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出取出就 ...

  5. android中私有方法 继承,Android项目实战系列—基于博学谷(五)个人资料

    由于这个模块内容较多,篇幅较长,请耐心阅读. 个人资料模块分为两个部分 [x] [个人资料]() [x] [资料修改]() 一.个人资料 1.个人资料界面 (1).创建个人资料界面 在com.buxu ...

  6. android中bmob云存储,Android中的Bmob移动后端云服务器功能

    PS:一般情况下,我们在写android程序的时候,想要实现登录注册功能,可以选择自己用servlet作为服务端来实现过滤没有注册过的用户,但是太麻烦,而且不是随时都可以用的.这里介绍一个移动后端云服 ...

  7. android获取外放设备,Android 监听耳机外放设备

    Android 设备插拔耳机状态监听:播放视频,音频切换(外放,耳机). 核心代码: import android.bluetooth.BluetoothAdapter; import android ...

  8. android中开启wifi,打开android系统设置,连接wifi

    打开android系统设置,连接wifi wifi信号强度:得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好,-50到-70表示信号偏差,小于-70表示最差,有可能连 ...

  9. android中的广播大全,android中的广播

    1系统广播(关闭,锁并,声音,电话,信号,等系统提供的广播)(例如信号) 广播一般是在一个类中直接写出来而不用这样单独写出到一个类中,这样方便在监听到结果时处理数据 import android.co ...

最新文章

  1. 帝国CMS附件大小限制
  2. leetcode96. 不同的二叉搜索树(动态规划)
  3. CORS跨域限制以及预请求验证(C++ Qt框架实现)
  4. 加载jsp页面报#{} is not allowed in template text
  5. ffmpeg获取设备支持的分辨率_Qt音视频开发6-ffmpeg解码处理
  6. 轻量级区块链协议Mina推出对抗性测试网“Testworld”
  7. 贪吃蛇javascript代码_源于Jquery开发贪吃蛇游戏——简单思路分析总结
  8. OpenCV基本线条操作
  9. SqlServer修改sa的密码
  10. win10多合一原版系统_如何制作Win10多合一系统安装盘
  11. 系统服务器更换技术方案,通道设备监控服务器更换 专项工程施工组织方案
  12. 分布式id黑科技完善
  13. 浅析Saas、PaaS、laas、Caas、Daas服务理解总结
  14. 微信支付API v3接口使用应用篇
  15. Navicat 的使用
  16. 2019 ,摧枯拉朽式的AI洗牌之路
  17. 如何将.m4a转.wav文件
  18. 删除薛定谔安装文件夹后导致无法卸载或重新安装解决方案(附正常卸载方法)
  19. 与技术无关-电视剧《小别离》经典台词
  20. 距离北京奥运还有359天,发布WPF版本的北京2008标志(下)

热门文章

  1. mysql 加密 en_以极少的停机时间加密运行 MySQL 或 MariaDB 的 Amazon RDS 数据库实例...
  2. 对InputStreamReader 和 OutputStreamWriter的理解
  3. 基于JAVA+SpringBoot+Vue+Mybatis+MYSQL的办公一体化系统
  4. 基于JAVA+SpringBoot+Mybatis+MYSQL的社区物业管理系统
  5. 目前网络时间服务有哪几种协议?
  6. 畅通工程---并查集
  7. 1.5 基础数据类型 -- 字典与集合
  8. 【转】Scala: Example use for early definition / early initializer / pre-initialized fields
  9. jquery.eq()
  10. 关于Bugzilla WebService接口