Android中的显式Intent与隐式Intent的使用
Intent是Android程序中各个组件中间进行交互的一种重要方式,它不仅仅可以指明当前组件想要执行的动作,还可以在不同组件之前传递数据。Intent一般可以被用于启动活动、启动服务以及发送广播等场景。Intent的使用可以分为两种:显式Intent与隐式Intent,接下来详细介绍。
显式Intent
- 显式Intent有多个构造函数,常用的2种写法如下:
Intent intent = new Intent(getApplicationContext(), SecondAct.class);
startActivity(intent);
Intent intent = new Intent();
intent.setClass(getApplicationContext(), SecondAct.class);
startActivity(intent);
getApplicationContext()用来获取上下文对象,也可以用当前activity的实例对象代替(例如FirstActivity.this)。后面的SecondAct.class就是指向你想跳转的活动Activity即可。
隐式Intent
原则上一个Intent不应该既是显式调用又是隐式调用,如果这两种共存的话,以显式为主。
隐式Intent调用的核心是Intent能够匹配目标组件中的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity。下面开始详细介绍IntentFilter。
IntentFilter
intentFilter中的过滤信息有action、category、data。为了匹配过滤列表,需要同时匹配过滤列表中的action、category、data信息,否则匹配失败。
一个过滤列表中action、category、data可以有多个,所有的action、category、data分别构成不同类别,同一类别的信息共同约束当前类别的匹配过程。只有一个Intent同时匹配action类别、category类别、data类别才算完全匹配,只有完全匹配才能成功启动目标activity。(一个activity可以有很多个intent-filter,一个intent只要能够匹配上任何一组intent-filter即可成功启动对应的activity)
<activity android:name=".SecondAct">
<intent-filter>
<action android:name="com.example.zwjian.myapplication.second" />
<action android:name="com.example.zwjian.myapplication.secondAct" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.zwjian.myapplication.category1" />
<category android:name="com.example.zwjian.myapplication.category2" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="com.example.zwjian.myapplication.s" />
<action android:name="com.example.zwjian.myapplication.d" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.zwjian.myapplication.category2" />
<category android:name="com.example.zwjian.myapplication.category3" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
action的匹配规则
action是一个字符串,系统已经定义了一些action,例如调用拨打电话、相机等等。我们也可以自己定义自己的action。action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配(字符串完全一样,区分大小写)。一个过滤规则中可以有很多action,那么只要Intent中的action能够和过滤规则中任何一个action相同即可匹配成功。。需要指出的是Intent中如果没有action,则匹配失败。概括一句话:action的匹配要求Intent中的action存在并必须和过滤规则中的其中一个action相同。
category的匹配规则
category是一个字符串,系统也是有一些预定义的category,同样我们也可以定义我们自己的category。category的匹配规则和action不同,它要求Intent中如果含有category,那么intent中的所有category都必须要和过滤规则中的category的其中一个相同。通俗的讲,就是指Intent中不管有几个category,都必须要在过滤规则中找到。需要指出的是:我们自己在使用intent的时候可以不设置category也可以实现跳转成功。这是因为我们在使用startActivity这行代码的时候,程序默认的会给intent加上“android.intent.category.DEFAULT”这个category。当然我们也要在目标activity的intentFilter中添加该条category。
data匹配规则
data的匹配规则和action相似,如果过滤规则中定义了data,那么intent中必须要定义可以匹配的data。
data由两部分组成,mimeType和URI。mimeType是指媒体类型,例如image/jpeg、video/*等。可以表示图片、文本、视频等不同的媒体格式。URI包含的数据比较多。URI结构如下:<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
- scheme表示的是URI的模式,比如说http、file、content等。如果URI中没有指定scheme,那么整个URI的其他参数无效,那么整个URI也无效。
- host代表主机名,例如www.baidu.com。如果host没有指定,那么也说明该URI无效
- port指的是端口号,只有指定了scheme和host之后post参数才有效
data匹配规则描述有点抽象,可以说个例子来直观了解:
<intent-filter>
<data android:mimeType="image/*"/>
</intent-filter>
上面的这个例子没有指定URI仅仅有mimeType,它指定了媒体类型为所有类型的图片,那么intent中的mimeType属性必须有“image/*”才能匹配。虽然没有指定URI,但是URI却有默认值,默认值是content和file。所以匹配结果如下:
intent.setDataAndType(Uri.parse("file://abc"),"image/png");
以上详细描述了隐式intent的调用匹配规则,那么我们可以看下前面所列的intent-filter中的过滤规则,然后写出我们自己的intent:
针对于第一个intent-filter(第二个忽略未写)
//匹配action
Intent intent =new Intent("com.example.zwjian.myapplication.second");
//匹配category,也可以不写,startActivity默认增加default的category
intent.addCategory("com.example.zwjian.myapplication.category1");
//匹配data
intent.setDataAndType(Uri.parse("file://abc"),"text/plain");
startActivity(intent);