Intent对象(三)显示隐式和<intent-filter>

Intent Resolution

Intent 有两种形式:

l 显示意图指定一个目标组件通过其name( Component name field), 由于组件名称通常不会被其它应用程序的开发者知道。所以,显示意图通常用在应用程序内部消息。----如:一个Activity 启动一个从属的service或者启动另一个activity

l 隐式意图不指定目标组件名称(component name 是空的)隐式意图通常用于去激活其它应用程序的组件

Android 传递了一个显示意图给一个被指定的目标类的实例 。被传递的 intent object 只是定义了component name -- 它决定了将会有那个组件去处理这个intent。

针对隐式意图需要不同的策略。在缺乏一个被指定的target的情况下,android系统必须找到最适合的组件去处理这个intent ---- 一个单一的activity 或者 service 去执行一个请求动作或者一组broadcase receiver 去响应广播通知.

它通过将intent 对象中的内容 和 意图过滤器(intent filters)进行比较。android系统根据intent filter打开可以接收intent的组件. 如果一个组件没有intent filter, 那么它只能接受显式intent. 如果有, 则能同时接受二者.。

Only three aspects of an Intent object are consulted when the object is tested against an intent filter:

当一个intent和intent过滤器进行比较时只会考虑以下三方面:

action  
data (both URI and data type)  
category

Intent filters

要告诉android系统哪个intent它们可以处理,activities,services,和 broadcast receivers 必须设置一个或者多个intent过滤器。每个过滤器描述了组件的一种能力,它过滤掉不想要的intent,留下想要的。显示意图则不用考虑这些。

一个过滤器中包含 一个Intent object 中的三个属性 action,data,catrgory 。一个隐式意图必须要通过这三项测试才能传递到 包含该过滤器的组件中。

测试1:Action test

<intent-filter . . . >
    <action android:name="com.example.project.SHOW_CURRENT" />
    <action android:name="com.example.project.SHOW_RECENT" />
    <action android:name="com.example.project.SHOW_PENDING" />
    . . .
</intent-filter>

如实例所示,当一个intent对象只能命名一个单一的action,一个过滤器则可以列出多个action。这个列表也可以是空的, 一个过滤器必须包含一个 <action> element ,否则它将阻止所有的intents要通过这个测试,在intent被指定的action必须匹配在过滤器中所列的action的其中之一。如果一个intent对象或者过滤器没有指定action。 结果如下 :

l 如果一个filter 没有指定任何action ,那么则没有任何intent会被匹配。所以,所有的intent将不会通过此测试。

l 另一方面,如果一个intent对象没有指定任何action,那么将自动通过此测试—只要这个过滤器中有至少一个action

测试2:Category test

<intent-filter . . . > 
<category android:name="android.intent.category.DEFAULT" /> 
<category android:name="android.intent.category.BROWSABLE" /> 
    . . . 
</intent-filter>

要通过category测试, Intent对象中包含的每个category必须匹配filter中的一个。Filter可以列出额外的category,但是不能漏掉 intent 对象包含的任意一个category。

原则上,一个没有任何categorys的 Intent object 将总是通过此测试。大多数情况下是正确的。然而,也有例外,android对待所有传入 startActivity() 中的隐式视图,都认为它们至少包含了一个 category --- "android.intent.category.DEFAULT". . 因此,希望接收这些隐式意图的activities必须在在它们的 intent filters 中包含”android.intent.category.DEFAULT” ..有(对于包含"android.intent.action.MAIN" and "android.intent.category.LAUNCHER"的filter 则是例外。因为它们标记了此activity开启了一个新的task 和 将出现在 auncher screen。它们也可以包含“com.intent.category.DEFAULT”,但没必要)

测试3:Data test

类似于action, categories, data也是 intent filter 中的一个子节点, 可以设置多个 data节点,也可以一个不设置。

如下图:

<intent-filter . . . > 
<data android:mimeType="video/mpeg" android:scheme="http" . . . /> 
<data android:mimeType="audio/mpeg" android:scheme="http" . . . /> 
    . . . 
</intent-filter>

每个< data > 元素可以指定一个 URI 和 一个 data type (MIME media type) . URI 有以下几个属性组成 : schema, host,port,path

Schema://host:port/path

例如:

content://com.example.project:200/folder/subfolder/etc

在上例中 schema 是 content: host: com.example.project

Port: 200 Path: folder/subfolder/etc

主机 host 和 port 一起组成了URI authority,如果没有指定 host,那么port将被忽略。

<data>节点中的属性都是可选的,但它们并非相互独立。要使一个authority 有意义,必须要指定 scheme 。 要是 path 有意义, scheme 和 authority(host:port) 必须指定。

当Intent对象中的URI 和 intent filter 进行比较时,它只会进行部门比较。 例如: 如果一个 filter 只指定了一个scheme , 那么所有包含该scheme的URI都会匹配。 如果一个filter只指定了 scheme 和 authority ,没有path, 那么所有包含此scheme 和 authority 将会匹配。如果一个filter指定了一个scheme,authority, 和一个path, 那么只有包含同样的 scheme,authoritym,path会匹配。 但是,对于path,我们可以使用通配符进行部门匹配。

<data>节点的 type 属性指定了 data的MIME type。 它比在filter中的URI 更常见 intent对象和filter都可以使用 “*” 通配符作为子类型 – 例如: "text/*" or "audio/*"--- 表示所有子类型都匹配。

data test 会将 intent对象中的URI 和 data type 与filter指定的都进行比较。 规则如下:

a) 如果一个intent 没有指定URI 和 data type , 那么如果filter中也是同样,则通过测试。

b) 如果一个iintent 有URI 但是没有 data type(或者是data type不能从uri中推断出来 ) 只能通过这样的filter: uri匹配, 并且不指定类型. 这种情况限于类似mailto:和tel:这样的不指定实际数据的uri.

c) 如果一个intent 包含 data type 但是没有 uri ,那么 filter中列出相同的data type 并且没有指定URI 则通过测试。

d) 如果一个intent包含一个URI 和data type (或者data type 可以从URI中推断出来),那么filter列出的有相同data type ,intent对象的uri要么和filter中的uri匹配,要么intent的uri为 content: or file: 并且filter不指定uri

如果一个Intent 可以通过多个activity或者filter的filter,那么用户将会被询问需要激活哪个组件。 如果一个都没有的话,将会抛出异常。

 

Common cases

这个规则是针对 data test 中的规则d) ,它反映出组件可以从一个file或者content provider 获取本地数据。因此,filters 可以是设置data type并且没有必要明确的将 scheme 命名为 content: 和 file: 。

下面的 <data>元素,告诉android该组件可以从content provider中获取image data 并显示她。

<data android:mimeType="image/*" />

由于大部分可用的数据都是由content provider提供, 指定数据类型但不指定uri的filter是最常见的情况.

Another common configuration is filters with a scheme and a data type. For example, a <data> element like the following tells Android that the component can get video data from the network and display it:

设置了 scheme 和 data type是 另一个比较常见的配置是 。下面的 <data>元素,告诉android该组件可以从网上获取video并显示

<data android:scheme="http" android:type="video/*" />

考虑当用户在一个web page上点了一个链接后,浏览器应用程序做了什么。 它首先会试图去显示该数据(当做一个html页来处理)。如果它不能显示此数据,它会使用一个设置 scheme 和 data type 的隐式意图 去启动一个能显示此数据的activity。如果没有找到接受者,它会调用下载管理器去下载该数据,然后将其放在content provider的控制之下,这样很多activitys (那些之命名了datatype)可以处理该数据

大部分应用程序还有一种方式可以单独启动,不用去引用特别的数据。那些要启动应用程序的activity 必须 设置 "android.intent.action.MAIN" 作为action。

如果还要显示在程序启动器上则必须设置 "android.intent.category.LAUNCHER" 为 category.

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值