关于intent的学习

来源:互联网 发布:新浪数据nba 编辑:程序博客网 时间:2024/05/29 17:41

此前作为一个应付作业的懒散家伙,intent在我这里基本就是理解为一个activity之间跳转的快递员,而且都是显示指定对方的情况。但是其实在androidManifest.xml里面的各种intent_filter的配置就是一直不明觉厉。所以今天特意补一下这方面知识,然后就感觉发现了新大陆。


此前我用的最多的毫无疑问就是Intent intent = new Intent(this,nextActivity.class);然后直接start了。呜,干净利落,多省事儿。此前在写javaWeb的时候也是这样简单粗暴。但是为啥不直接启动另一个activity,还要搞一个intent?呜,作为一个嫌struts麻烦没用的懒货只好在这里接受一下教训。面向接口,低耦合什么的全部白学了。直接启动会造成硬编码耦合不说,启动的对象就至少有activity,service,broadcastreceiver这么一大堆,自然要使用一个统一的编程模型。


Intent其实就是用来启动activity,service,broadcastReceiver这些东西的组件。我之前将其理解为信使其实还是有很大问题的,因为intent实际做的是封装了程序想要启动组件的意图,当然,还会附带传递一下bundle。Intent大致包含七大属性:component,action,category,data,type,extra,flag七大属性。


component其实就是上面强行显式启动相关的属性,Intent intent = new Intent(this,nextActivity.class);其实也可以转换成如下代码:

Component component = new Component(this,nextActivity.class);Intent intent = newIntent();intent.setComponent(component);

指定component属性的intent已经明确将要启动哪个组件,因此也被称为显式intent,没有指定component属性的intent则称为隐式intent,这时候就要通过其它几个属性找对象了。


action,category属性的值都是普通的字符串,action代表intent需要完成的一个抽象动作,并不清楚需要完成的对象。而category则用于为action添加额外的附加类别信息。在此之前我一直以为ACTION和category其实就是一个activity在配置文件中声明的启动条件,intent只能声明一个action,声明多个category,而只要有被配置的activity中有一个action符合且category全部满足就可以启动该activity。这样的理解中action和category更像是一个身份辨识,更像是一组唯一身份的标识符。在这样的用法里面这样理解其实也不是完全错误。但是在看到android赋予一些action和category的标准常量就会发现action和category确实更应该理解为行为和意义。呜,不是很清楚博客里面怎么用表格,有朋友需要看的话可以直接百度标准action常量和标准category,举个例子:

<activity android:name=".view.MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>

这里的action.MAIN就是程序入口的行为,而category.LAUNCHER则是显示顶级程序列表的意思。另外还有android.intent.action.VIEW和android.intent.action.EDIT分别表示查看和编辑,至于查看和编辑什么就是其它属性指定的事情了。launcher比较抽象,但是换成android.intent.category.HOME就比较直接了,直接从程序里面回到手机home界面,就像按了home键一样。


上面说的action只提供行为,但不提供操作对象,而data属性就是用来提供操作对象的。data属性接受uri对象(scheme://host:port/path)供action使用,而type和action不分家,用于指定data属性所指定的URI对应的MIME类型。intent其实要分两边编辑,一个是xml里面的intent-filter,一个是java里面的新建的intent对象,前面那个是受,后面那个是攻(呜,糟糕的比方,勿怪)。在data这里就分在两边说:


在java这边:data属性和type属性会相互覆盖,后声明的那个会覆盖先声明的那个,要同时声明得调用intent的setDataAndType()方法


而在intent-filter这里则是通过<data.../>元素,格式如下:

<data android:mimeType=""    android:scheme=""    android:host=""    android:port=""    android:path=""    android:pathProfix=""    android:pathPattern=""/>

其中mimeType即java中type属性,而后三个属性可以总结为path。type属性必须被满足才能启动该activity,但是data属性,则是分为scheme,host,port,path四个部分,优先级从前到后,如果intent-filter中只指定了前面若干个,则只需要满足这几个即可,但必须是从前到后。比如指明了scheme,port则有效的只有scheme。被声明的部分必须相同才能启动对应组件。这时候就有可能出现启动多个组件需要进行选择的问题了hh,因为scheme,host,port都符合条件时,可以有只声明scheme,声明了scheme,host,声明scheme,host,port的三个组件响应。


action和data一起的时候其实更能说明问题:

Intent intent = new Intent();String data = "http://www.baidu.com";Uri uri = Uri.parse(data);intent.setAction(Intent.ACTION_VIEW);intent.setData(uri);startActivity(intent);

以上代码便可以打开网页。动作是ACTION_VIEW查看,对象是data属性。结果就是访问网页。


Extra属性没什么好说的,就是activity之间的数据交换。而flag则是功能繁多的控制信号。