Android中的信息传递机制通过Intent来实现
intent可以启动Activity Service 和Broadcast receiver
一个Intent对象的组成
组件名:
要启动的组件的名字,比如一个Activity名,一个Service名,是最简单的Intent启动方式
Action:
Action可以是一些系统设置好的常量:Activity的Intent中代表要执行的Action,如ACTION_VIEW ACTION_EDIT ,Broadcat的Intent中代表action发生和报告的时机,如ACTION_BATTERY_LOW等
也可以是自己定义的常量,用来激活你应用程序中的组件,命名最好加上包名,比如"zxc.android.learning.SHOW_MSG",这样保证Action的唯一性
Data:
要处理数据的URI(统一资源标识符)和数据的类型
不同的action匹配不同的数据URI,比如ACTION_EDIT,后面的data匹配的就是显示出来进行编辑的文档,比如ACTION_CALL,后面的data就应该是tel:xxxxx,如果是ACTION_VIEW而后面的data是http: 那么要调用的Activity就会下载并显示资源
大多数情况下,数据类型可以从URI格式上推测出来,比如开头是content: 这个数据存储在手机设备上并且被ContentProvider控制
如果调用setData方法声明数据只是一个URI setType方法声明数据只是一个MIME类型,setDataAndType声明即是一个URI又是一个MIME类型
Category:
一个字符串,包含了哪类组件可以处理这个intent
Extras:
Intent中携带的键值对,有一些是对应的Action带有的,也可以是自定义放入的 putExtras() getExtras()
Flags:
用来指示Android系统以什么样的方式启动一个Activity和启动之后的设置
Intent的分类
明确的Intent,指定了要启动的组件名,一般用来激活自己应用程序中的组件
不明确的Intent,一般用来启动别的应用程序中的组件
在处理不明确的Intent的时候,Android系统必须为这个Intent找到一个合适的处理组件,比如一个Activity或者一个Service或者一个接受Broadcast公告的BroadcastReceiver
android系统通过对比<<要处理的Intent中的内容>>和组件的<<intent-filter>> ,intent-filters说明了组件的 能力 和能处理的 intent 的类型
如果一个组件没有声明intent-filter,那么其只能处理明确的intent,如果声明了intent-filter,既可以处理明确的Intent也可以处理不明确的Intent
一个要被处理Intent的action data(uri和type) category 这三个方面作为标记被用来和intent-filter对比,来决定哪些控件可以处理这个Intent
Intent filters
Activity,Service,BroadcastReceiver组件可以声明一个或者多个intent-filter来告诉系统,哪些不明确的Intent他们可以处理
每一个intent-filter描述了控件的一种能力,实际上也是说这个组件想要的是什么样的<不明确Intent>, 过滤掉那些不想要的 不明确Intent (明确的Intent不受intent-filter影响)
<activity android:name=".NoteEditor">
<intent-filter>
<action android:name="android.intent.action.EDIT"> <!--对应intent中的ACTION_EDIT--!>
<action android:name="android.intent.action.VIEW"> <!--对应intent中的ACTION_VIEW--!>
</intent-filter>
</activity>
这样就说明这个activityt可以进行文档的编辑和显示功能
一般来说,系统需要在启动一个组件之前就知道它的能力,所以一般需要在manifest.xml文件中进行intent-filter的定义
有一个例外情况是broadcastReceiver的动态注册registReceiver方法
一个intent-filter的组成对应intent,也有<action> <data> <category>,一个intent必须与intent-filter的这三个元素完全匹配才能传递给这个组件
当一个组件拥有好几个intent-filter时,intent只要与其中一个匹配就能传递
<action> 一个intent的action必须与intent-filter中的任何一个匹配才能通过,如果一个<intent-filter>中一个<action>都没有,那么所有的不明确intent都不能通过
如果一个intent没有action,就可以忽略intent-filter(废话,这就成了明确的intent)
<category>一个category,如果一个intent中没有定义category,那么就可以忽略intent-filter中category的内容,一个例外就是,
要接收非明确intent的Activity必须要有
<category android:name="android.intent.category.DEFAULT">,除非这个Activity是程序启动的Activity,有MAIN和LAUNCHER category.
<data>
<data android:mimeType="video/mpeg" android:scheme="http"...> //"text/*" "audio/*"代表text任何子类型都满足,audio下的任何子类型都满足
<data android:mimeType="audio/mpeg" android:scheme="http"...>
URI的完整为 scheme://host:port/path,比如content://zxc.android.learning:200/folder/subfolder 如果host没有指定,port也被忽略
一个Intent在和intent-filter对比时,只对比intent-filter中有的项
比如android的桌面Launcher,也是一个应用程序,也由一个个Activity组成
AppList通过查找所有带<intent-filter><category android:name="android.intent.category.LAUNCHER">的activity,并把他们的图标和文本显示在一个gridView上
Launcher里有一个带有<intent-filter><category android:name="android.intent.category.HOME">的activity,在点击手机上HOME键的时候会发送一个category为....HOME的intent来启动Launcher中的这个activity,也就是主界面!
以在Android SDK中的Example NotePad为例,其中mimeType部分,选择返回数据怎样实现???