安卓进阶专题篇-Intent

       Android的三个基本组件——Activity,Service和Broadcast Receiver——都是通过Intent机制激活的,不同类型的组件有不同的传递Intent方式,我们经常使用intent,但若不认真分析intent,确经常云里雾里的.

     那么什么是intent呐,意图,就是你要通过i可以通过intent干些什么事。是一个将要执行的动作的抽象的描述,由Intent来协助完成android各个组件之间的通讯。比如调用Activity实例化对象的startActivity()来启动一个activity,或者由broadcaseIntent()来传递给所有感兴趣的BroadcaseReceiver, 或者由startService()/bindservice()来启动一个后台的service。可见,intent主要用来启动activity或者service(并携带需要传递的参数信息),intent理解成activity之间的粘合剂。

总之,Intent具有激活组件和携带数据的功能!
         具体的三大组件的Intent方式:
    1.1 要激活一个新的Activity,或者让一个现有的Activity做新的操作,可以通过调用Context.startActivity()或者Activity.startActivityForResult()方法。 

           1.2 要启动一个新的Service,或者向一个已有的Service传递新的指令,调用Context.startService()方法或者调用Context.bindService()方法将调用此方法的上下.Intent形式文对象与Service绑定。

           1.3 Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()这三个方法可以发送Broadcast Intent。发送之后,所有已注册的并且拥有与之相匹配IntentFilter的BroadcastReceiver就会被激活。 

Intent一旦发出,Android都会准确找到相匹配的一个或多个Activity,Service或者BroadcastReceiver作响应。所以,不同类型的Intent消息不会出现重叠,即Broadcast的Intent消息只会发送给BroadcastReceiver,而决不会发送给Activity或者Service。由startActivity()传递的消息也只会发给Activity,由startService()传递的Intent只会发送给Service。

       Intent形式

(1).显示意图(Explicit Intents)
       明确指定组件名的Intent为显式意图,指定了Intent应该传递给那个组件。通过下面代码方式,可以创建显示意图实例化对象,并设定需要传递的参数信息。由于显示意图指定了具体的组件对象,不需要设置intent的其它意图过滤对象。
[java]  
//  1.创建Intent实例化对象几种方式  
  
Intent intent = new Intent();  
intent.setClass(Context packageContext, Class<?> cls) ;           //内部调用setComponent(ComponentName)  
intent.setClassName(Context packageContext, String className) ; //内部调用setComponent(ComponentName)  
intent.setClassName(String packageName, String className) ;     //内部调用setComponent(ComponentName),可以激活外部应用  
  
intent.setComponent(new ComponentName(this, Class<?> cls));  
intent.setComponent(new ComponentName(this, "package Name"));  
2).隐式意图(Implicit Intents)
没有明确指定组件名的Intent为隐式意图,系统会根据隐式意图中设置的 动作(action)、类别(category)、数据URI等来匹配最合适的组件。
1).action
The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, 包括Android 系统指定的 和 自定义
[java]  
intent.setAction("com.baidu.action.TEST");  
[html] view plaincopy
<action android:name="com.baidu.action.TEST"/>  
2).data
expressed as a Uri, The data to operate on, such as a person record in the contacts database.
系统自带的Action简单举例
Action Data(Uri) Content
ACTION_VIEW
content://contacts/people/1
Display information about the person whose identifier is "1".
ACTION_VIEW
tel:123
Display the phone dialer with the given number filled in.
ACTION_DIAL
tel:123
Display the phone dialer with the given number filled in.
 自定义data匹配
[java]  
intent.setData(Uri.parse("baidu://www.baidu.com/news"));  
[html]  
<!-- android:path 内容字符串需要以 / 开头 -->  
<data android:scheme="baidu" android:host="www.baidu.com" android:path="/news"/>  
3).category
Gives additional information about the action to execute.
注意:项目清单的xml文件意图过滤器中必须指定 android.intent.category.DEFAULT类别,Activities will very often need to support the CATEGORY_DEFAULT so that they can be found by Context.startActivity,or Context can‘t the acitivity component
[java]  
intent.addCategory("com.baidu.category.TEST");  
[html] 
<!-- 必须指定CATEGORY_DEFAULT,只有这样startActivity(intent)才能找到 -->  
<category android:name="com.baidu.category.TEST" />  
<category android:name="android.intent.category.DEFAULT" />  
除了以上主要属性外,下面还有其它属性可以额外增强。
4).type
Specifies an explicit type (a MIME type) of the intent data.
[java]  
intent.setType("image/jpeg");  
[html] view plaincopy
<data android:mimeType="image/*" />  
注意:java文件中data Uri 和 type不能同时使用各自的函数进行设定,因为使用type时会把Uri清除掉,可以使用setDataAndType方法设定
[java] 
intent.setDataAndType(Uri.parse("baidu://www.baidu.com/news"), "image/jpeg");  
[html]  
<data android:mimeType="image/*" android:scheme="baidu" android:host="www.baidu.com" android:path="/news"/>  
(3).两者的使用区别
 显式意图一般在应用的内部使用,因为在应用内部已经知道了组件的名称,直接调用就可以了。
当一个应用要激活另一个应用中的Activity时,只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。

ntent解析机制

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有<intent-filter>及其中定义的Intent,通过PackageManager(注:PackageManager能够得到当前设备上所安装的
application package的信息)来查找能处理这个Intent的component。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:
1.1  如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;
1.2  如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
1.3  如果Intent中的数据不是content:类型的URI,而且Intent也没有明确指定type,将根据Intent中数据的scheme(比如 http:或者mailto:)进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。
1.4 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。