您的位置:华清远见教育科技集团 >> Android资料 >> Android Intent激活组件  
 
Android Intent激活组件
分享到:

在Android中,应用组件也是通过Intent来激活的,其中内容提供器是通过ContentResolver发出请求的方式来激活的,而Activity、服务和广播接收器则是通过所谓的Intent异步消息的方式来激活的。

利用Intent激活组件的操作方法有:startActivity(Intent)、startService(Intent)、bindService(Intent, ServiceConnection, int)、sendBroadcast(Intent)等,其中 startActivity()方法用于发起Activity,startService()方法用于发起服务,bindService()方法用于绑定服务,而 sendBroadcast()方法则用来向所有关联的广播接收器发送广播。

为了能收到Intent消息,AndroidManifest.xml 的“intent-filter”元素必须包含至少一个“action”元素,否则Intent过滤器会过滤掉所有的Intent消息。

在通信过程中,Intent负责对通信消息进行描述,Android则根据Intent的描述,找到匹配的组件,将 Intent传递给匹配的组件,并完成组件的调用。如在文件管理器中,为了打开一个文件,相应Intent的实现如下:

Intent activityIntent = new Intent(Intent.ACTION_VIEW);
    activityIntent.setDataAndType(path, mimetype);
    activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(activityIntent);

如果实在希望了解是否有匹配的组件存在,可以做如下的判断:

public static boolean isRecognizedFileType(Context context, Uri fileUri, String mimetype)
    {
        boolean ret = true;
        if (D) Log.d(TAG, "RecognizedFileType() fileUri: " + fileUri + " mimetype: " +
mimetype);
        Intent mimetypeIntent = new Intent(Intent.ACTION_VIEW);
        mimetypeIntent.setDataAndType(fileUri, mimetype);
        List< ResolveInfo> list = context.getPackageManager().queryIntentActivities(mimetypeIntent,PackageManager.
MATCH_DEFAULT_ONLY);
        if (list.size() == 0)
        {
            if (D) Log.d(TAG, "NO application to handle MIME type " + mimetype);
            ret = false;
        }
        return ret;
    }

因此,Intent在通信过程中起着媒介的作用,专门传递组件互相调用的相关信息,实现了调用者与被调用者之间的解耦。

在Android中,Intent携带的信息主要有两种属性:行为(Action)和数据(Data)。其他属性还有类别(Category)、数据类型(Type)、组件(Component)、附加信息(extras)等。

·“Action”属性是对所执行消息主旨的描述,对常见的Action,如查看、编辑、拨号等,Android在系统层面进行了定义,如DIAL_ACTION、MAIN_ACTION、 VIEW_ACTION、EDIT_ACTION。对特殊的行为,允许开发者自定义。

·“Data”属性即所执行消息涉及的数据,在Android中采用指向数据的URI来表示。如content://contacts/people/1,意思为电话簿中标识符为“1”的条目信息。

·“Category”属性即所执行消息的附加信息。例如,LAUNCHER_CATEGORY 表示Intent 的目标Activity应该作为应用主界面出现;而ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选行为中的一个,这些行为可以在同一块数据上执行。

·“Type”属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置“Type”属性,可以显示指定数据类型。

·“Component”属性指定Intent的目标组件的类名。通常 Android会根据Intent 中包含的其他属性的信息,如Action、Sata、Type、Category等属性进行解析,终找到一个与之匹配的目标组件。但是如果指定“Component”属性,将直接使用其指定的组件,而不再执行上述解析过程。指定该属性后,Intent的其他所有属性均变为可选属性。该属性在Activity的相互调用中经常使用。

·“extras”属性是其他所有附加信息的集合。使用“extras”属性可以为组件提供扩展信息,比如如果要执行“发送电子邮件”,可以将电子邮件的标题、正文等保存在“extras”属性里,传给电子邮件发送组件。这给程序开发带来了较强的灵活性。该属性在传递数据时经常使用。

在Android中,根据是否声明“Component”属性的不同,Intent可以分为显式Intent和隐式Intent两种。

其中显式Intent即指定了“Component”属性的Intent(代码实现为通过调用setComponent()方法或setClass()方法)。通过指定具体的组件类,通知应用启动对应的组件。

隐式Intent即没有指定“Component”属性的Intent。这类Intent需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,解析出匹配此Intent的组件。

对于显式Intent,Android不需要去做解析,因为目标组件已经很明确,Android需要解析的是那些隐式Intent,通过解析,将 Intent传递给匹配此Intent的Activity、IntentReceiver或服务。实际的Activity的解析是通过resolveActivity()进行的。

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有Intent过滤器及其中定义的 Intent,终找到匹配的组件。在解析过程中,Android依赖于Intent的Action、Type、Category等属性,解析策略如下:

·如果Intent声明“Action”属性,则目标组件的Intent过滤器的Action列表中就必须包含该Action,否则不能匹配。

·如果Intent没有声明“Type”属性,系统将从“Data”属性中得到数据的类型。和Action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

·如果Intent中的“Data”属性不是“content:”类型的URI,且没有声明“Type”属性,系统将根据Intent中数据的协议类型(scheme,如http:、mailto:)进行匹配。同上,Intent 的协议类型必须出现在目标组件的协议类型列表中。

·如果Intent为“Category”属性赋予了多个类别值,这些类别必须全部出现在组件的类别列表中。假如Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

当希望能够对一个外部的事件(来电、电量发生变化等)做出响应时,开发者需要注册一个Intent过滤器。Intent接收器在关联的事件发生时,会通知应用收到的事件,各种应用还可以通过使用Context.broadcastIntent()方法将Intent 消息广播给其他应用程序。

Intent过滤器可以在AndroidManifest.xml中注册,如为了接收打开相应类型的音频文件的请求,相应的Intent过滤器如下:

< intent-filter>
        < action android:name="android.intent.action.VIEW" />
        < category android:name="android.intent.category.DEFAULT" />
        < data android:scheme="content"/>
        < data android:host="media"/>
        < data android:mimeType="audio/*"/>
        < data android:mimeType="application/ogg"/>
        < data android:mimeType="application/x-ogg"/>
        < data android:mimeType="application/itunes"/>
    < /intent-filter>

部分开发者可能搞不明白MIME类型的含义,有时可能自我想象的确定MIME类型,殊不知MIME类型是有规范的,对于每一种文件类型,其标识符唯一。

Intent的标志位主要有FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_ CLEAR_TOP、FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 、FLAG_ACTIVITY_SINGLE_ TOP等,这些标志位的详细含义可以参考Android的帮助文档。

 更多相关文章

·Android Broadcast的使用
·详解Android Service组件
·Android应用组件Activity
·Android RPC管道文件系统
·Android RPC远程调用