Intent的一些知识点
Intent的用途
Intent
是一个消息传递对象。使用Intent
向系统请求操作,主要包括:
- 启动
Activity
- 启动
Service
- 发送
Broadcast
下图展示了启动Activity
时,Intent
在两个Activity
之间如何传递的
Intent类型
官方的说法:
- 显式
Intent
:通过提供目标应用的软件包名称或完全限定的组件类名来指定可处理Intent
的应用 - 隐式
Intent
:不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理
是否指定组件是区别显式和隐式Intent
的关键。显式Intent
启动指定的组件,而隐式Intent
通过声明执行的操作向系统请求操作。
构造显式Intent
可通过Intent
构造器、setComponent(ComponentName)
、setClassName(Context, String)
、setClassName(String, String)
、setClass(Context, Class<?>)
指定组件。
Activity如何声明接收隐式Intent
Activity
想要接收隐式Intent
,必须在manifest
中的声明中添加<intent-filter>
元素,在<intent-filter>
内部,可使用action
、data
、category
三个元素的一个或多个指定要接收的Intent
类型。
action
前提条件:一个Activity
可以声明一个或多个action
,未声明action
表示不接受隐式Intent
;一个Intent
不设置或只能设置一个action
。
匹配条件:Activity
声明的action
必须包含想要接收的隐式Intent
的action
。
category
前提条件:一个Activity
可以声明一个或多个category
,一个Intent
也可以包含一个或多个category
。
重点:**Intent
不存在没有category
的情况,因为使用startActivity
或startActivityForResult
启动隐式Activity
时会自动将CATEGORY_DEFAULT
应用到Intent
中,所以Activity
中至少有一个android.intent.category.DEFAULT
**
匹配条件:Activity
声明的所有category
必须包含Intent
的所有category
。
data
data
分为两部分:MIME
和URI
。MIME
和URI
各自有匹配的规则,非常简单,这里就不说了。
前提条件:一个Activity
可以声明0个、一个或多个data
,一个Intent
也可以包含0个或一个data
。
- 当
Activity
未声明data
时,只能接受无data
的Intent
- 只声明了
URI
的Activity
,只能接受只有且能够匹配URI
部分的data
的Intent
- 只声明了
MIME
的Activity
,接受能够匹配MIME
的data
的Intent
,或是能够匹配MIME
,URI
是content
或file
类型数据的Intent
- 声明了
URI
和MIME
的Activity
,只能接受URI
和MIME
同时匹配的Intent
注意其中有点差异的是,之声明了MIME
部分的Activity
,可以接受content
或file
类型URI
数据的Intent
。
一个可接受隐式Intent的Activity的过滤器的友好设计
- 声明一个或多个想要接收的
action
- 声明至少一个
category
————android.intent.category.DEFAULT
,若想要被浏览器启动,还需要声明android.intent.category.BROWSABLE
- 声明一个或多个想要接收的
data
,若想要接收文件类型的data
,可以只声明MIME
- 可声明多个
<intent-filter>
接收多种过滤器 - (很少使用)若是不想其他
app
启动,则可以添加"exported"=false
。
总结
这个规则其实很简单,我们通常会在打开相机、访问文件时使用隐式Intent
调动系统组件。反过来,我们想在其他应用如浏览器打开我们的app
时,就需要自己声明过滤器,这时就要站在编写<intent-filter>
的角度来看待Intent
的过滤规则,这是之前一直困扰我,没能够友好理解Intent
的关键。