Android-Intent
2020-09-16 本文已影响0人
有腹肌的豌豆Z
Intent简介
Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
Intent可分为隐式(implicitly)和显式(explicitly)两种:
显式 Intent
- 即在构造Intent对象时就指定接收者,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的,如下:
Intent intent = new Intent(MainActivit.this, NewActivity.class);
startActivity(intent );
隐式 Intent
- 即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合,它一般用在没有明确指出目标组件名称的前提下,一般是用于在不同应用程序之间。
Intent intent = new Intent();
intent.setAction("com.wooyun.test");
startActivity(intent);
对于组件发送intent有不同的机制:
启动Activity
- 使用Context.startActivity() 或 Activity.startActivityForResult(),传入一个intent来启动一个activity。使用 Activity.setResult(),传入一个intent来从activity中返回结果。
启动Service
- 将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service。将intent对象传给 Context.bindService()来绑定一个service。
启动Broadcast
- 将intent对象传给 Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被传给 broadcast receiver。
Intent Filter匹配规则
- Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。
- 在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行匹配判断的。
- 一个过滤列表中的action、type、category可以有多个,所有的action、type、category分别构成不同类别,同一类别信息共同约束当前类别的匹配过程。
- 只有一个Intent同时匹配action、type、category这三个类别才算完全匹配,只有完全匹配才能启动Activity。
- 另外一个组件若声明了多个Intent Filter,只需要匹配任意一个即可启动该组件。
action的匹配规则
- action是一个字符串,如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配。
- 一个Intent Filter中可声明多个action,Intent中的action与其中的任一个action在字符串形式上完全相同(注意,区分大小写,大小写不同但字符串内容相同也会造成匹配失败),action方面就匹配成功。
- 可通过setAction方法为Intent设置action,也可在构造Intent时传入action。
- 需要注意的是,隐式Intent必须指定action。
比如我们在Manifest文件中为MyActivity定义了如下Intent Filter:
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<action android:name="android.intent.action.SEND_TO"/>
</intent-filter>
那么只要Intent的action为“SEND”或“SEND_TO”,那么这个Intent在action方面就能和上面那个Activity匹配成功。比如我们的Intent定义如下:
Intent intent = new Intent("android.intent.action.SEND") ;
startActivity(intent);
Android系统预定义了许多action,这些action代表了一些常见的操作。
Intent.ACTION_VIEW
Intent.ACTION_DIAL
Intent.ACTION_SENDTO
Intent.ACTION_SEND
Intent.ACTION_WEB_SEARCH
data的匹配规则
- 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,同action类似,只要Intent的data只要与Intent Filter中的任一个data声明完全相同,data方面就完全匹配成功。
- data由两部分组成:mimeType和URI 。
- MineType指的是媒体类型:例如imgage/jpeg,auto/mpeg4和viedo/*等,可以表示图片、文本、视频等不同的媒体格式 。
- uri则由scheme、host、port、path | pathPattern | pathPrefix这4部分组成。
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern >]
看这个格式是不是很熟悉 又是 Scheme
- Intent的uri可通过setData方法设置,mimetype可通过setType方法设置。
- 需要注意的是:若Intent Filter的data声明部分未指定uri,则缺省uri为content或file,Intent中的uri的scheme部分需为content或file才能匹配;若要为Intent指定完整的data,必须用setDataAndType方法,究其原因在,setData和setType方法的源码中我们发现:
public Intent setData(Uri data) {
mData = data;
mType = null;
return this;
}
public Intent setType(String type) {
mData = null;
mType = type;
return this;
}
category的匹配规则
- category也是一个字符串,但是它与action的过滤规则不同,它要求Intent中个如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。
- 也就是说,Intent中如果出现了category,不管有几个category,对于每个category来说,它必须是过滤规则中的定义了的category。
- 当然,Intent中也可以没有category(若Intent中未指定category,系统会自动为它带上“android.intent.category.DEFAULT”),如果没有,仍然可以匹配成功。
- category和action的区别在于,action要求Intent中必须有一个action且必须和过滤规则中的某几个action相同,而category要求Intent可以没有category,但是一旦发现存在category,不论你有多少,每个都要能够和过滤规则中的任何一个category相同。