Intents and Intent Filters
一 intent是什么?
Intent(意图)主要是解决Android应用的各项组件之间的通讯。
Android的官网说了3个主要功能
1 . 启动activity 通过 startActivity()或者 startActivityForResult()
2 启动service通过startService()或者bindServer启动Server
3 发送广播通过sendBroadcast(),sendOrderedBroadcast(), or sendStickyBroadcast().
二 intent的类型
1. 显式(Explicit)
指定显式意图启动组件名称(完全限定类名)。你通常会使用一个明确的意图在你自己的应用程序中启动一个组件(例如 Activity,Server..),因为你知道你想要开始的Activity或Server的类别名称。例如,启动一个新的Activity以响应用户操作或启动服务来下载后台文件。
就是我们平常调用的startActivity() , startService() 指定类名去启动一个组件
2. 隐式(Implicit) intent
不要将某个特定的组件命名,而是声明一个一般的action来执行,这允许一个组件从另一个应用程序来处理它。例如,如果你想显示用户在地图上的位置,你可以使用隐式的意图要求,另一个有能力的应用程序在地图上显示指定的位置。
就是没有明确的指定要启动哪个Activity,而是通过设置一些Intent Filter来让系统去筛选合适的Acitivity去启动。
当您创建一个隐含的意图,安卓系统找到适当的组件开始比较的intetn的intent filter 声明在该设备上的其他应用程序的清单文件中声明的意图。如果intent匹配到一个intent filter过滤器,系统启动该组件并提供它的意图对象。如果多个意图过滤器是兼容的,系统会显示一个对话框,用户可以选择哪个应用程序使用。就像这样
三 intent的组成
1. Component name 组件名称
Component name 是显示intent经常使用的. Intetn类里有一个方法
public IntentsetComponent(ComponentName component) ;
ComponentName 里有两个变量String mPackage, String mClass
是哪个包什么class . 就好像我们经常使用的方法
Intent intent =new Intent(MainActivity.this,SecondActivity.class);
简单的说 就是明确指定名称要去哪个组件. 换句话说就是显式intent.
2 Action:
命名动作的字符串 , 就是在AndroidManifest intent filter 上的action.
像下面的action . 如果系统找到action来匹配, 如果只有一个就直接跳过去,假如不是的话就弹窗. 例如 发短信 , 播放视频都是通过action来
<activityandroid:name=".TwoActivity">
<intent-filter>
<actionandroid:name="com.example.qiang.intentoneapp.ACTION_VIEW"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
3 Data :
起到表示数据和数据MIME类型的作用。不同的action是和不同的data类型配套的。比如,action是ACTION_EDIT,那么data要包含要编辑的文档URI。如果action是ACTION_CALL,data可能是tel:前缀后面跟电话号码,在比如action是ACTION_VIEW,data是http:开头的URI,则应该是显示或者下载该uri的内容。在匹配intent到能处理该组件的过程中,data(MIME类型)类型是很重要的。比如,一个组件是可以显示图片数据的而不能播放声音文件。很多情况下,data类型可在URI中找到,比如content:开头的URI,表明数据在设备上,而且有content provider控制。但是有些类型只能显式的设置。setData()方法只能设置data的uri,setType()可设置MIME类型,setDataAndType()即可设置URI也可设置MIME类型。
什么是MIME ?一、MIME TYPE描述
多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。
参考:http://blog.chinaunix.net/uid-20159689-id-3695291.html
说明是个通用的东西, 在web上都有使用 , 不是安卓所独有的.
关键怎么用?举个栗子
显示网页:
1. Uri uri =Uri.parse("http://www.google.com");
2. Intent it = newIntent(Intent.ACTION_VIEW,uri);
3. startActivity(it);
拨打电话:
1. Uri uri = Uri.parse("tel:xxxxxx");
2. Intent it = newIntent(Intent.ACTION_DIAL, uri);
3. startActivity(it);
Data 主要通过是Intent的 public Intent setData(Uri data)这个方法设置进去 . 接收的参数的Uri .
那我们又要去了解Uri .. 应该怎么设置Uri.
参考 http://blog.csdn.net/sunny09290/article/details/7514963
(1) 组成
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string"/>
包含在<intent-filter>
语法 <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
举个实际的例子:
content://com.example.project:200/folder/subfolder/etc
\---------/ \---------------------------/\---/ \--------------------------/
scheme host port path
\--------------------------------/
authority
4 Category (类别)
包含处理intent组件种类的额外信息。对一个Intent可以设置任意多个category描述,和cation类似,Intent类预制了一些category常量,Intent.CATEGORY_*。
比较常用的Category
CATEGORY_BROWSABLE 跳到浏览器
CATEGORY_LAUNCHER 应用程序的默认启动Activity ,在androidManifest.xml
有什么用?
比如有这样的隐式的intent :
<activityandroid:name=".TwoActivity">
<intent-filter>
<actionandroid:name="com.example.qiang.intentoneapp.ACTION_VIEW"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
intent想通过测试,必须匹配一个intentfilter中的category。
原理上讲,intent如果没有category设置,那么总是可以通过测试。这基本上是正确的,但是有一个例外。Android在为所有隐式intent执行startActivity()方法的时候,会认为它们至少包含了一个android.intent.category.DEFAULT。因此,如果activity想收到隐式intent,必须加入这个category。
5 Flags
用于多种情况,在intent增加flug,比如可以指示Android如何启动一个activity,比如是否属于或者不属于当前task,以及,处理完毕后activity的归属。这些flag都定义在Intent类的常量中。
1.FLAG_ACTIVITY_CLEAR_TOP:例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launch mode设置成singleTask类似。简而言之,跳转到的activity若已在栈中存在,则将其上的activity都销掉。
2.FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。注意如果试图从非activity的非正常途径启动一个activity(例见下文“intent.setFlags()方法中参数的用例”),比如从一个service中启动一个activity,则intent比如要添加FLAG_ACTIVITY_NEW_TASK标记(编者按:activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈,所以要新起一个栈装入启动的activity)。简而言之,跳转到的activity根据情况,可能压在一个新建的栈中。
3.FLAG_ACTIVITY_NO_HISTORY:例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。简而言之,跳转到的activity不压在栈中。
4.FLAG_ACTIVITY_SINGLE_TOP:和Activity的Launch mode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。简而言之,目标activity已在栈顶则跳转过去,不在栈顶则在栈顶新建activity。
参考
http://blog.csdn.net/jason0539/article/details/10049899
http://www.cnblogs.com/stay/articles/1932022.html
http://blog.csdn.net/sunny09290/article/details/7514963
http://blog.csdn.net/ygc87/article/details/7480695
http://blog.csdn.net/berber78/article/details/7278408