欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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传递就是了。比如可以把这个树节点存到全局变量里,目的组件直接访问这个全局变量即可。