Android 使用Intent传递数据的实现思路与代码
程序员文章站
2023-12-02 18:53:40
intent是android中一个非常重要的概念,跟这个词的本意(意图,目的)一样,这个类在android中的作用就是要调用某个组建去做某一件事,比如通过startacti...
intent是android中一个非常重要的概念,跟这个词的本意(意图,目的)一样,这个类在android中的作用就是要调用某个组建去做某一件事,比如通过startactivity启动一个activity,通过startservice启动一个service,通过sendbroadcast发送一个广播等,它相当于各个组建间的一个桥梁。很重要的一点是这个过程是可以跨进程的,比如在应用中可以启动调用某个播放器组件(系统自身的或者第三方的)来播放一段视频,启动照相机程序拍照等等。
当我们启动视频播放器播放一段视频的时候,首先要告诉播放器播放哪个视频文件,这就涉及到intent的数据传递功能,intent传递数据有两种方式:setdata,putextra。前者的参数是uri,uri是全局的可以访问的数据的一个标识,比如磁盘上的一个文件,数据库中的一个联系人等,后者的参数可以是具体的基本数据类型和对象。对于对象,传递的是对象的成员,包括基本的数据成员和成员对象。intent要求传递的对象以及其成员对象实现了serializable或者parcelable,是可以持久化的(考虑到跨进称传递,可以理解,可能先在传递前,把对象保存到一个缓冲区域,然后再从这个区域取)。
当初次接触android时,有过一个的困惑,先看代码:
// mycls
class mycls implements seriliazable
{
public string mvalue;
}
// activitya
mycls mmycls;
// 跳转到activityb
intent intent = new intent();
mmycls = new mycls();
mmycls.mvalue = "activitya";
intent.putserializable("mycls", mmycls);
intent.setclass(this, activityb.class);
startactivity(intent);
// activityb
mycls cls = (mycls)getintent().getserializable("mycls");
cls.mvalue = "activityb";
我的疑惑是:在activityb中,把cls的mvalue更改了,为什么activitya里,mmycls.mvalue没变?难道b中cls是a中mmycls的拷贝吗,为什么api没讲到?当初长时间纠结于intent传递的是对象引用还是对象的拷贝而不得解,上网查资料也没有任何这方面的解答。而现在可以释然了,相信有同样疑惑的读者看了这篇文章后也会释然。
对于复杂对象,现在例举树节点做说明,一个树节点,其成员对象有父节点和子节点的队列,在用intent传递这样一个节点时,会不断递归,导致实际上传递的是整棵树!如果这个树比较膨大的话,效率会十分低。transient修饰符可以解决这个问题,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。我们可以在节点中把父节点和子节点队列修饰为transient,这样在传递的过程中就不会传递它们,接收时,父节点和子节点为null。但是很显然这样会导致信息丢失了。
一般而言会有这样的情况:不用跨进程访问其它组件,而传递的复杂对象又需要保证完整的信息不丢失,怎么办呢?很简单,既然在同一进程中,内存对大家都是可访问的,用intent传递这个对象真是牛刀杀鸡了,不用intent传递就是了。比如可以把这个树节点存到全局变量里,目的组件直接访问这个全局变量即可。
当我们启动视频播放器播放一段视频的时候,首先要告诉播放器播放哪个视频文件,这就涉及到intent的数据传递功能,intent传递数据有两种方式:setdata,putextra。前者的参数是uri,uri是全局的可以访问的数据的一个标识,比如磁盘上的一个文件,数据库中的一个联系人等,后者的参数可以是具体的基本数据类型和对象。对于对象,传递的是对象的成员,包括基本的数据成员和成员对象。intent要求传递的对象以及其成员对象实现了serializable或者parcelable,是可以持久化的(考虑到跨进称传递,可以理解,可能先在传递前,把对象保存到一个缓冲区域,然后再从这个区域取)。
当初次接触android时,有过一个的困惑,先看代码:
复制代码 代码如下:
// mycls
class mycls implements seriliazable
{
public string mvalue;
}
// activitya
mycls mmycls;
// 跳转到activityb
intent intent = new intent();
mmycls = new mycls();
mmycls.mvalue = "activitya";
intent.putserializable("mycls", mmycls);
intent.setclass(this, activityb.class);
startactivity(intent);
// activityb
mycls cls = (mycls)getintent().getserializable("mycls");
cls.mvalue = "activityb";
我的疑惑是:在activityb中,把cls的mvalue更改了,为什么activitya里,mmycls.mvalue没变?难道b中cls是a中mmycls的拷贝吗,为什么api没讲到?当初长时间纠结于intent传递的是对象引用还是对象的拷贝而不得解,上网查资料也没有任何这方面的解答。而现在可以释然了,相信有同样疑惑的读者看了这篇文章后也会释然。
对于复杂对象,现在例举树节点做说明,一个树节点,其成员对象有父节点和子节点的队列,在用intent传递这样一个节点时,会不断递归,导致实际上传递的是整棵树!如果这个树比较膨大的话,效率会十分低。transient修饰符可以解决这个问题,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。我们可以在节点中把父节点和子节点队列修饰为transient,这样在传递的过程中就不会传递它们,接收时,父节点和子节点为null。但是很显然这样会导致信息丢失了。
一般而言会有这样的情况:不用跨进程访问其它组件,而传递的复杂对象又需要保证完整的信息不丢失,怎么办呢?很简单,既然在同一进程中,内存对大家都是可访问的,用intent传递这个对象真是牛刀杀鸡了,不用intent传递就是了。比如可以把这个树节点存到全局变量里,目的组件直接访问这个全局变量即可。
推荐阅读
-
Android 使用Intent传递数据的实现思路与代码
-
Android TableLayout数据列表的回显清空实现思路及代码
-
Android中获取网页表单中的数据实现思路及代码
-
Android开发使用json实现服务器与客户端数据的交互功能示例
-
Android编程实现全局获取Context及使用Intent传递对象的方法详解
-
Android中获取网页表单中的数据实现思路及代码
-
Java数据结构与算法:图、图的概念、深度优先搜索DFS、广度优先搜索BFS、思路分析、代码实现
-
Vuex数据持久化实现的思路与代码
-
Android 用Intent实现活动之间数据的传递
-
Vuex数据持久化实现的思路与代码