android中intent放数据类型,Android Intent传递数据底层分析详细介绍
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传递数据底层分析详细介绍相关推荐
- Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家
Android Intent传递数据底层分析详细介绍 我们知道在Activity切换时,如果需要向下一个ActivityB传递数据,可以借助Intent对象的putExtra方法. 但是不知各位有没 ...
- Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
Android中使用HttpURLConnection实现GET POST JSON数据与下载图片 Android6.0中把Apache HTTP Client所有的包与类都标记为deprecated ...
- android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...
1.0 可以利用Intent吧数据传递给上一个活动,新建一个叫"hellotest01"的项目. 新建活动FirstActivity,勾选"Generate Layout ...
- 使用显式Intent向下一个活动传递数据
在启动活动时传递数据的思路很简单,Intent提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出取出就 ...
- android中私有方法 继承,Android项目实战系列—基于博学谷(五)个人资料
由于这个模块内容较多,篇幅较长,请耐心阅读. 个人资料模块分为两个部分 [x] [个人资料]() [x] [资料修改]() 一.个人资料 1.个人资料界面 (1).创建个人资料界面 在com.buxu ...
- android中bmob云存储,Android中的Bmob移动后端云服务器功能
PS:一般情况下,我们在写android程序的时候,想要实现登录注册功能,可以选择自己用servlet作为服务端来实现过滤没有注册过的用户,但是太麻烦,而且不是随时都可以用的.这里介绍一个移动后端云服 ...
- android获取外放设备,Android 监听耳机外放设备
Android 设备插拔耳机状态监听:播放视频,音频切换(外放,耳机). 核心代码: import android.bluetooth.BluetoothAdapter; import android ...
- android中开启wifi,打开android系统设置,连接wifi
打开android系统设置,连接wifi wifi信号强度:得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好,-50到-70表示信号偏差,小于-70表示最差,有可能连 ...
- android中的广播大全,android中的广播
1系统广播(关闭,锁并,声音,电话,信号,等系统提供的广播)(例如信号) 广播一般是在一个类中直接写出来而不用这样单独写出到一个类中,这样方便在监听到结果时处理数据 import android.co ...
最新文章
- 帝国CMS附件大小限制
- leetcode96. 不同的二叉搜索树(动态规划)
- CORS跨域限制以及预请求验证(C++ Qt框架实现)
- 加载jsp页面报#{} is not allowed in template text
- ffmpeg获取设备支持的分辨率_Qt音视频开发6-ffmpeg解码处理
- 轻量级区块链协议Mina推出对抗性测试网“Testworld”
- 贪吃蛇javascript代码_源于Jquery开发贪吃蛇游戏——简单思路分析总结
- OpenCV基本线条操作
- SqlServer修改sa的密码
- win10多合一原版系统_如何制作Win10多合一系统安装盘
- 系统服务器更换技术方案,通道设备监控服务器更换 专项工程施工组织方案
- 分布式id黑科技完善
- 浅析Saas、PaaS、laas、Caas、Daas服务理解总结
- 微信支付API v3接口使用应用篇
- Navicat 的使用
- 2019 ,摧枯拉朽式的AI洗牌之路
- 如何将.m4a转.wav文件
- 删除薛定谔安装文件夹后导致无法卸载或重新安装解决方案(附正常卸载方法)
- 与技术无关-电视剧《小别离》经典台词
- 距离北京奥运还有359天,发布WPF版本的北京2008标志(下)
热门文章
- mysql 加密 en_以极少的停机时间加密运行 MySQL 或 MariaDB 的 Amazon RDS 数据库实例...
- 对InputStreamReader 和 OutputStreamWriter的理解
- 基于JAVA+SpringBoot+Vue+Mybatis+MYSQL的办公一体化系统
- 基于JAVA+SpringBoot+Mybatis+MYSQL的社区物业管理系统
- 目前网络时间服务有哪几种协议?
- 畅通工程---并查集
- 1.5 基础数据类型 -- 字典与集合
- 【转】Scala: Example use for early definition / early initializer / pre-initialized fields
- jquery.eq()
- 关于Bugzilla WebService接口