显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent。显式Intent直接用组件的名称定义目标组件,这种方式很直接。但是由于开发人员往往并不清楚别的应用程序的组件名称,因此,显式Intent更多用于在应用程序内部传递消息。比如在某应用程序内,一个Activity启动一个Service。
隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent。它不会用组件名称定义需要激活的目标组件,它更广泛地用于在不同应用程序之间传递消息.由于没有明确的目标组件名称,所以必须由Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。

隐式启动Intent

  Android系统寻找与Intent请求意图最匹配的组件具体的选择方法是:
Android将Intent的请求内容和一个叫做IntentFilter的过滤器比较,IntentFilter中包含系统中所有可能的待选组件.如果IntentFilter中某一组件匹配隐式Intent请求的内容,那么Android就选择该组件作为该隐式Intent的目标组件。
Android如何知道应用程序能够处理某种类型的Intent请求呢?这需要应用程序在Android-Manifest.xml中声明自己所含组件的过滤器(即可以匹配哪些Intent请求)。
一个没有声明Intent-Filter的组件只能响应指明自己名字的显式Intent请求,而无法响应隐式Intent请求。 
一个声明了IntentFilter的组件既可以响应显式Intent请求,也可以响应隐式Intent请求。在通过和 IntentFilter比较来解析隐式Intent请求时,Android将以下三个因素作为选择的参考标准Action \Data\ Category,而Extra和Flag在解析收到Intent时是并不起作用的

Intent过滤器:

  应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描述该组件所能响应Intent请求——组件希望接收什么类型的请求行为,什么类型的请求数据。
如何为组件声明自己的Intent Filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的Intent Filter。
隐式Intent和Intent Filter进行比较时的三要素是Intent的动作、数据以及类别。实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目标组件。接下来我们讲解这三方面检查的具体规则。

Android ASM 过滤类名 android 过滤器_Android

Action测试:<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-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。
如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。
如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。 (1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent- filter>匹配; (2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个 Intent请求就将顺利地通过<intent-filter>的行为测试。

Category测试:<intent-filter > <category android:name=”android.Intent.Category.DEFAULT” /> <category android:name=”android.Intent.Category.BROWSABLE” /> </intent-filter>   
只有当Intent请求中所有的Category与组件中某一个IntentFilter的<category>完全匹配时,才会让该 Intent请求通过测试.
IntentFilter中多余的<category>声明并不会导致匹配失败。
一个没有指定任何类别测试的 IntentFilter仅仅只会匹配没有设置类别的Intent请求。

Data测试:

<intent-filter> <data android:type=”video/mpeg” android:scheme=”http” . . /> <data android:type=”audio/mpeg” android:scheme=”http” . . /> </intent-filter>   
<data>元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Inteat请求的URI数据类型和scheme必须与IntentFilter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会通过测试

演示一个例子,用Intent隐身启动activity,并显示Action和Category的值,这个例子用到了两个Activity,两个布局,要注意到是在AndroidMainFest里设置uses-permission

首先来看布局文件main.xml




Android ASM 过滤类名 android 过滤器_java_02

Android ASM 过滤类名 android 过滤器_java_03

View Code


1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical"
 4     android:layout_width="fill_parent"
 5     android:layout_height="fill_parent"
 6     >
 7 <Button android:id="@+id/bt1"
 8     android:layout_width="fill_parent" 
 9     android:layout_height="wrap_content" 
10     android:text="intent隐身启动test"
11     />
12 </LinearLayout>



second.xml文件




Android ASM 过滤类名 android 过滤器_java_02

Android ASM 过滤类名 android 过滤器_java_03

View Code


1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3   xmlns:android="http://schemas.android.com/apk/res/android"
 4   android:orientation="vertical"
 5   android:layout_width="match_parent"
 6   android:layout_height="match_parent">
 7   <EditText android:id = "@+id/et1"
 8       android:layout_width="fill_parent"
 9       android:layout_height="wrap_content"/>
10   <EditText android:id ="@+id/et2"
11       android:layout_width="fill_parent"
12       android:layout_height="wrap_content"/>
13 </LinearLayout>



然后给大家看一下AndroidMainFest里的代码




Android ASM 过滤类名 android 过滤器_java_02

Android ASM 过滤类名 android 过滤器_java_03

View Code


1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3       package="cn.shaoyangjiang.com"
 4       android:versionCode="1"
 5       android:versionName="1.0">
 6     <uses-sdk android:minSdkVersion="8" />
 7 
 8     <application android:icon="@drawable/icon" android:label="@string/app_name">
 9         <activity android:name=".IntentFilterActivity"
10                   android:label="@string/app_name">
11             <intent-filter>
12                 <action android:name="android.intent.action.MAIN" />
13                 <category android:name="android.intent.category.LAUNCHER" />
14             </intent-filter>
15         </activity>
16 
17         <activity android:name=".Second"
18                   android:label="@string/app_name">
19         <intent-filter>
20         <!-- 指定该Activity能响应action为指定字符串的Intent -->
21                 <action android:name="cn.shaoyangjiang.cn.com" />
22         <!-- 指定该Activity能响应category为指定字符串的Intent -->
23                 <category android:name="cn.shaoyangjiang.cn" />
24         <!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
25                 <category android:name="android.intent.category.DEFAULT" />   
26             </intent-filter>      
27         </activity>    
28     </application>
29     <uses-permission android:name="android.permission.READ_CONTACTS" />
30     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
31 </manifest>



第三步:修改intentfilterActivity.java文件

  




Android ASM 过滤类名 android 过滤器_java_02

Android ASM 过滤类名 android 过滤器_java_03

View Code


1 package cn.shaoyangjiang.com;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 
10 public class IntentFilterActivity extends Activity {
11     //定义一个Action常量
12     final static String shao = "cn.shaoyangjiang.cn.com"; 
13     //定义一个Category常量
14     final static String yang = "cn.shaoyangjiang.cn";
15     @Override
16     public void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(R.layout.main);
19         Button button1 = (Button)findViewById(R.id.bt1);
20         button1.setOnClickListener(new OnClickListener() {        
21             @Override
22             public void onClick(View arg0) {
23                 Intent intent = new Intent();
24                 //设置Action属性
25                 intent.setAction(shao);
26                 //添加Category属性
27                 intent.addCategory(yang);
28                 startActivity(intent);
29             }
30         });
31     }
32 }



最后一部是second.java文件




Android ASM 过滤类名 android 过滤器_java_02

Android ASM 过滤类名 android 过滤器_java_03

View Code


1 package cn.shaoyangjiang.com;
 2 
 3 import java.util.Set;
 4 import android.app.Activity;
 5 import android.os.Bundle;
 6 import android.widget.EditText;
 7 
 8 public class Second extends Activity{
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.second);
13         EditText editText1 =(EditText)findViewById(R.id.et1);
14         //获取该Activity对应的Intent的Action属性
15         String actionValue = getIntent().getAction();
16         //显示Action属性
17         editText1.setText("Action: "+actionValue);
18         EditText editText2 = (EditText)findViewById(R.id.et2);
19         //获取该Activity对应的Intent的Category属性
20         Set<String> cate= getIntent().getCategories();
21         //显示Action属性
22         editText2.setText("Categoties: "+cate);    
23     }    
24 }



效果图:

Android ASM 过滤类名 android 过滤器_java_12

Android ASM 过滤类名 android 过滤器_android_13