1. 什么是意图
Android四大组件:活动、服务、广播、内容提供者。活动、服务、广播这些组件之间的调用和消息传递都是通过意图实现的,意图是一种消息机制
1.1 意图与目标组件
意图就像是快递源,穿行在各个组件之间。意图有三种主要的方式来实现组件间的通信:
- 启动活动。通过将意图对象传递给活动的startActivity()方法或startActivityForResult()方法来启动一个活动。
- 启动服务。通过将意图对象传递给服务startService()方法启动一份本地服务,通过将意图传递给服务bindService()方法,连接一个远程服务。
- 发送广播。通过调用给广播接收器sendBroadcast()等方法可将广播发送给其他应用。
1.2 意图包含
意图对象包含:目标组件(Component)、动作(Action)、数据(Data)、类别(Category)、附加数据(Extra)、标志(Flag)。其中目标组件可以帮助应用发送显式意图调用请求,动作、数据、类别可以构建一个意图过滤器。意图过滤器可以帮助应用发送隐式意图调用请求,实现查询目标组件。附加数据用于传递参数给目标组件,标志是指目标组件任务行为。
2. Intent常用构造方法
-
Intent() 创建一个没有任何意图的Intent对象,该对象可以使用 setActio (String action) 方法添加相应的动作,以便体现Intent对象的意图,例如: Intent intent = new Intent();
intent. setAction(Intent. ACTION_DIAL);
-
Intent(String action) 创建一个Intent 对象,该对象中的动作由参数 action 来描述 ,例如: Intent intent= new Intent(Intent. ACTION_DIAL);
也就是说 Intent(String action) 构造方法的关键是通过一个动作来构造 Intent对象,即通过 个动作来体现一个意图 -
lntent(String action, Uri uri) lntent(String action, Uri uri) 构造方法的关键是通过一个动作 action 和一个 Uri 类型的数据 uri 来体现 一个意图,即构造 Intent 对象,例如: Uri uri =Uri.parse("tel: 13887698765");
Inten intent = new Intent (In ent ACTION DIAL,u立);
那么, Intent 对象体现的意图就是"拨打电话 13887698765", 即该意图是通过一个动作"拨打电话”和一个数据 “13887698765” 来体现的。 Ur parse 方法会从 “tel: 13887698765” 中解析出 一个 电话号码 “13887698765” 放到Uri 对象中,比如,对于Uri uri=Uri. parse(“tel:-lpolicelO”); Uri 对象中的电话号码110。
上述三个构造方法创建的 Intent 对象所体现的意图被习惯地称为隐式意图 (ImplicitIntents) , 即没有明确给出启用哪个 Activity 对象来完成意图,因此使用上述构造方法创建 Intent 对象,可能启动多个 Activity 对象。比如, Intent 类的静态常量VIEW 表示的动作是将数据显示给用户(甚至没有说显示怎样类型的数据),那么程序执行下列代码后:
Intent intent= new Intent(Intent. ACTION_ VIEW);
startAcvity(intent);
startActivity(Intent intent) 方法在手机(或 AVD)的Android 系统内找到有多个 Activity 对象能完成这个意图(这些Activity 主要是显示系统内部的一些数据),因此列出了所有Activity 对象,让用户选择其中一个Activity 对象,并激活所选择的 Activity 对象。
3. 意图类型
意图分为两种类型:显示意图(Explicit Intent)和隐式意图(Implicit Intent)
3.1 显示意图
显示意图是通过指定组件名称直接启动组件,可以通过下面的方法实现显示意图。Intent类中方法
- setComponent(ComponentName name)。其中ComponentName类是Android框架提供的组件封装类,需要提供包名、类名或context上下文对象。
- setClassName(String packageName,String classNameInThatPackage)。提供包名和目标组件类名。
- setClassName(Context context,String classNameInThatContext)
- setClass(Context context,Class classObjectInThatContext)
除了上述方法外,可以在直接构造意图对象时,指定context对象和目标组件类型
Intent intent =new Intent(LoginActivity.this,FailureActivity.class);
startActivity(intent);
3.2 隐式意图
隐式意图用于不同应用之间调用。因此隐式意图请求要提供意图过滤器,目标组件要在它所在的应用的AndroidManidest.xml中注册该组件和意图过滤器。
<activity android:name=".AppStart">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
4. 匹配组件
为了能够找到应用程序的组件,Android通过一些隐式意图请求实现。Android系统查找所有与意图匹配的意图过滤器,然后启动目标组件。步骤如下:
- Activity A创建包含动作、数据、类别等信息的隐式意图,并将其传递给startActivity(),交给Android系统。
- Activity 系统查找相匹配的应用组件,即满足目标组件声明的意图过滤器条件。
- 如果找到匹配的过滤器,Android系统启动目标组件
在匹配时,通过三个意图属性考虑匹配
一个隐式意图要求能够传递给目标组件,必须要通过这三个属性的检查,如任意一方不匹配,Android都不会将该隐式意图传递给目标组件。
4.1 动作(Action)
动作是指定意图要执行的任务。动作是用一个字符串常量描述。 意图对象中的动作可以通过 setAction() 方法来设置,也可以在创建 Intent 的同时进行设置,通过 getAction() 方法来读取。
常量名称 | 常量值 | 意义/描述 |
---|
ACTION_MAIN | android.intent.action.MAIN | 应用程序入口 | ACTION_VIEW | android.intent.action.VIEW | 显示数据给用户 | ACTION_ATTACH_DATA | android.intent.action.ATTACH_DATA | 指明附加信息给其他地方的一些数据 | ACTION_EDIT | android.intent.action.EDIT | 显示可编辑的数据 | ACTION_PICK | android.intent.action.PICK | 选择数据 | ACTION_CHOOSER | android.intent.action.CHOOSER | 显示一个Activity选择器 | ACTION_GET_CONTENT | android.intent.action.GET_CONTENT | 获得内容 | ACTION_DIAL | android.intent.action.GET_CONTENT | 显示打电话面板 | ACITON_CALL | android.intent.action.DIAL | 直接打电话 | ACTION_SEND | android.intent.action.SEND | 直接发短信 | ACTION_SENDTO | android.intent.action.SENDTO | 选择发短信 | ACTION_ANSWER | android.intent.action.ANSWER | 应答电话 | ACTION_INSERT | android.intent.action.INSERT | 插入数据 | ACTION_DELETE | android.intent.action.DELETE | 删除数据 | ACTION_RUN | android.intent.action.RUN | 运行数据 | ACTION_SYNC | android.intent.action.SYNC | 同步数据 | ACTION_PICK_ACTIVITY | android.intent.action.PICK_ACTIVITY | 选择Activity | ACTION_WEB_SEARCH | android.intent.action.WEB_SEARCH | Web搜索 | ACTION_FACTORY_TEST | android.intent.action.FACTORY_TEST | 工厂测试入口点 | ACTION_SEARCH | android.intent.action.SEARCH | 搜索 |
举例选择发短息 在AndroidManifest.xml文件中。指定SENDTO动作过滤器的代码如下
<activity android:name=".SendActivity">
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
隐式意图需要设置这个动作才能匹配,代码如下:
Intent intent=new Intent();
intent.setAction(Intent.ACTION_SENDTO);
startActivity(intent);
自定义动作 可以在自己的应用中指定动作,他的命名规则一般是“应用包名+自己动作” 在AndroidManifest.xml文件中代码如下:
<activity android:name=".SuccessActivity">
<intent-filter>
<action android:name="com.a51work6.loginsample.SUCCESS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
隐式意图的设置
private static final String ACTION_APP_SUCCESS ="com.a51work6.loginsample.SUCCESS";
Intent intent =new Intent();
intent.setAction(ACTION_APP_SUCCESS);
startActivity(intent);
4.2 数据(Data)
数据是指定目标组件需要的数据,他是由指定数据的URI和数据的MIME类型两部分组成的。 URI是统一资源标识符,它可以指定一个资源 MIME类型是资源的数据类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型。 添加数据的意图过滤器在AndroidManifest.xml中代码如下
<intent-filter>
....
<data android:mimeType="sudio/MP3" android:scheme="http"..../>
</intent-filter>
android:scheme属性设置URI中scheme,此外还包括android:host、android: port、android:path
隐式意图设置数据代码如下:
Intent intent =new Intent();
Uri playUri =new Uri.parse("www.51work6.com/mp3/ma_mma.mp3");
intent.setDataAndType(playUri,"audio/MP3");
startActivty(intent);
在隐式意图中,单独设置MIME类型使用setType()方法,单数设置Uri使用setData()方法,但是如果同时设置MIME和Uri必须使用setDataAndType()方法。同时使用setType()方法和setData()方法会覆盖数据。
4.3 类别(Category)
类别包含了请求组件的一些附加信息。常用的类别有两种
- android.intent.category.LAUNCHER和android.intent,action.MAIN动作一起使用,表明该活动是一个启动的活动
<activity android:name=".AppStart">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- android.intent.category.DEFAULT,指定默认的类别,意图过滤器必须要指定一个类别,默认情况下可以使用该类别
<activity android:name=".FailureActivity">
<intent-filter>
<action android:name="com.a51work6.loginsample.FALLURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
每一个通过测试的隐式意图都至少有一个类别,如果没有别的类别指定,默认要指定android.intent.category.DEFAULT;如果没有任何类别,系统会抛出异常。
自定义类别 AndroidManifest.xml
<activity android:name=".SuccessActivity">
<intent-filter>
<action android:name="com.a51work6.loginsample.SUCCESS" />
<category android:name="com.a51work6.loginsample.SUCCESS" />
<data android:mimeType="text/html"/>
</intent-filter>
</activity>
隐式意图代码
public static final String ACTION_APP_SUCCESS ="com.a51work6.loginsample.SUCCESS";
public static final String CATEGORY_APP_SUCCESS="com.a51work6.loginsample.SUCCESS";
....
Intent intent =new Intent();
intent.setAction(ACTION_APP_SUCCESS);
intent.addCategory(String CATEGORY_APP_SUCCESS);
...
startActivity(intent);
附加数据(Extra)和 标志(Flag)在Android第2讲中提过 后续文章持续更新中。。。。
|