intent学习总结

 

这么长时间对intent 一直不是很了解,在网上看了几篇文章,在机子上实验了下,记录下自己的学习。

 

Android 中提供了 Intent 机制来协助应用间的交互与通讯,或者采用更准确的说法是, Intent 不仅可用于应用程序之间,也可用于应用程序内部的 Activity/Service 之间的交互。 Intent 的使用中你看不到直接的函数调用,相对函数调用来说, Intent 是更为抽象的概念,利用 Intent 所实现的软件复用的粒度是 Activity/Service ,比函数复用更高一些,另外耦合也更为松散。

Android 中与 Intent 相关的还有 Action/Category Intent Filter 等,另外还有用于广播的 Intent ,这些元素掺杂在一起,导致初学者不太容易迅速掌握 Intent 的用法。



 

 

SDK 中给出了Intent 作用的表现形式为:

Intent 属性的设置 ,包括以下几点:(以下为XML 中定义,当然也可以通过Intent 类的方法来获取和设置)

1Action ,也就是要执行的动作

SDk 中定义了一些标准的动作,包括

onstant

Target component

Action

ACTION_CALL

activity

Initiate a phone call.

ACTION_EDIT

activity

Display data for the user to edit.

ACTION_MAIN

activity

Start up as the initial activity of a task, with no data input and no returned output.

ACTION_SYNC

activity

Synchronize data on a server with data on the mobile device.

ACTION_BATTERY_LOW

broadcast receiver

A warning that the battery is low.

ACTION_HEADSET_PLUG

broadcast receiver

A headset has been plugged into the device, or unplugged from it.

ACTION_SCREEN_ON

broadcast receiver

The screen has been turned on.

ACTION_TIMEZONE_CHANGED

broadcast receiver

The setting for the time zone has changed.

 

当然,也可以自定义动作(自定义的动作在使用时,需要加上包名作为前缀,如"com.example.project.SHOW_COLOR ),并可定义相应的Activity 来处理我们的自定义动作。

2Data ,也就是执行动作要操作的数据

Android 中采用指向数据的一个URI 来表示,如在联系人应用中,一个指向某联系人的URI 可能为:content://contacts/1 。对于不同的动作,其 URI 数据的类型是不同的(可以设置type 属性指定特定类型数据),如ACTION_EDIT 指定Data 为文件URI ,打电话为tel:URI ,访问 网络为http:URI ,而由content provider 提供的数据则为content: URIs

3type (数据类型),显式指定Intent 的数据类型(MIME )。一般Intent 的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

4category (类 别),被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher 中作为顶级应用出现;而ALTERNATIVE_CATEGORY 表示当前的Intent 是一系列的可选动作中的一个,这 些动作可以在同一块数据上执行。还有其他的为

Constant

Meaning

CATEGORY_BROWSABLE

The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.

CATEGORY_GADGET

The activity can be embedded inside of another activity that hosts gadgets.

CATEGORY_HOME

The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.

CATEGORY_LAUNCHER

The activity can be the initial activity of a task and is listed in the top-level application launcher.

CATEGORY_PREFERENCE

The target activity is a preference panel.

 

5component (组 件),指定Intent 的的目标组件的类名称。通常 Android 会根据Intent 中包含的其它属性的信息,比如actiondata/typecategory 进行查找,最终找到一个与之匹配的目标组件。但是,如果 component 这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent 的其它所有属性都是可选的。

6extras (附加信息),是其它所有附加信息的集合。使用extras 可以为组件提供扩展信息,比如,如果要执行 发送电子邮件 这个动作,可以将电子邮件的标题、正文等保存在extras 里,传给电子邮件发送组件。

 

理解 Intent 的关键之一是理解清楚 Intent 的两种基本用法:一种是显式的 Intent ,即在构造 Intent 对象时就指定接收者,这种方式与普通的函数调用类似,只是复用的粒度有所差别;另一种是隐式的 Intent ,即 Intent 的发送者在构造 Intent 对象时,并不知道也不关心接收者是谁,这种方式与函数调用差别比较大,有利于降低发送者和接收者之间的耦合。另外 Intent 除了发送外,还可用于广播。

对于显式IntentAndroid 不需要去做解析,因为目标组件已经很明确,Android 需要解析的是那些隐式Intent ,通过解析,将 Intent 映射给可以处理此IntentActivityIntentReceiverService        

Intent 解析机制主要是通过查找已注册在AndroidManifest.xml 中的所有IntentFilter 及其中定义的Intent ,最终找到匹配的 Intent 。在这个解析过程中,Android 是通过Intentactiontypecategory 这三个属性来进行判断的,判断方法如下:

  • 如果 Intent 指明定了 action ,则目标组件的 IntentFilter action 列表中就必须包含有这个 action ,否则不能匹配;
  • 如果 Intent 没有提供 type ,系统将从 data 中得到数据类型。和 action 一样,目标组件的数据类型列表中必须包含 Intent 的数据类型,否则不能匹配。
  • 如果 Intent 中的数据不是 content: 类型的 URI ,而且 Intent 也没有明确指定它的 type ,将根据 Intent 中数据的 scheme (比如 http: 或者 mailto : 进行匹配。同上, Intent scheme 必须出现在目标组件的 scheme 列表中。
  • 如果 Intent 指定了一个或多个 category ,这些类别必须全部 出现在组建的类别列表中。比如 Intent 中包含了两个类别: LAUNCHER_CATEGORY ALTERNATIVE_CATEGORY ,解析得到的目标组件必须至少包含这两个类别。

Intent-Filter 的定义

一些属性设置的例子:

<action android:name="com.example.project.SHOW_CURRENT" />



<category android:name="android.intent.category.DEFAULT" />



<data android:mimeType="video/mpeg" android:scheme="http" . . . /> 



<data android:mimeType="image/*" />



<data android:scheme="http" android:type="video/*" />



Intent 用法实例

1. 无参数 Activity 跳转

Intent it = 



new





Intent(Activity.Main.



this


, Activity2.


class










);







startActivity(it);   





 

2. 向下一个 Activity 传递数据(使用 Bundle Intent.putExtras

Intent it = 



new





Intent(Activity.Main.



this


, Activity2.


class


);











Bundle bundle=



new





Bundle();







bundle.putString("



name






", "



This is from MainActivity!






");







it.putExtras(bundle);      





// it.putExtra(“test”, "shuju”);










startActivity(it);           





// startActivityForResult(it,REQUEST_CODE);


 

对于数据的获取可以采用:

Bundle bundle=getIntent().getExtras();







String name=bundle.getString("



name


");


 

3. 向上一个 Activity 返回结果(使用 setResult ,针对 startActivityForResult(it,REQUEST_CODE) 启动的 Activity

        



Intent intent=getIntent();







       


Bundle bundle2=



new





Bundle();







       


bundle2.putString("



name


", "


This is from ShowMsg!


");



       


intent.putExtras(bundle2);







       


setResult(RESULT_OK, intent);



4. 回调上一个 Activity 的结果处理函数( onActivityResult

@Override















   





protected










 





void










 


onActivityResult(



int










 


requestCode,



int










 


resultCode, Intent data) {







       





// TODO Auto-generated method stub










       





super


.onActivityResult(requestCode, resultCode, data);







       





if


(requestCode==REQUEST_CODE){







           





if


(resultCode==RESULT_CANCELED)







                 


setTitle("



cancle


");







           





else





if


(resultCode==RESULT_OK) {







                


String temp=



null


;







                


Bundle bundle=data.getExtras();







                





if


(bundle!=


null


)  


temp=bundle.getString("



name


");







                


setTitle(temp);







           


}







       


}







   


}


















应用例子





















       



Android SDK


中的便笺例子(上面的XML


文件)来说明,Intent


如何定义及如何被解析。这个应用可以让用户浏览便笺列表、查看每一个便笺的详细信息。



       






















例子中的第一个 Activity com.google.android.notepad.NotesList ,它是应用的主入口,提供了三个功能,分别由三个 intent-filter 进行描述:
        1
、第一个是进入便笺应用的顶级入口( action android.app.action.MAIN )。类型为 android.app.category.LAUNCHER 表明这个 Activity 将在 Launcher 中列出。
        2
、第二个是,当 type vnd.android.cursor.dir/vnd.google.note (保存便笺记录的目录) 时,可以查看可用的便笺( action android.app.action.VIEW ),或者让用户选择一个便笺并返回给调用者( action android.app.action.PICK )。
        3
、第三个是,当 type vnd.android.cursor.item/vnd.google.note 时,返回给调用者一个用户选择的便笺 action android.app.action.GET_CONTENT ),而用户却不需要知道便笺从哪里读取的。 有了这些功能,下面的 Intent 就会被解析到 NotesList 这个 activity

  • { action=android.app.action.MAIN } :与此 Intent 匹配的 Activity ,将会被当作进入应用的顶级入口。
  • { action=android.app.action.MAIN, category=android.app.category.LAUNCHER } 这是目前 Launcher 实际使用的 Intent ,用于生成 Launcher 的顶级列表。
  • { action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes } 显示 "content://com.google.provider.NotePad/notes" 下的所有便笺的列表,使用者可以遍历列表,并且察看某便笺的详细信息。
  • { action=android.app.action.PICK data=content://com.google.provider.NotePad/notes } 显示 "content://com.google.provider.NotePad/notes" 下的便笺列表,让用户可以在列表中选择一个,然后将选择的便笺的 URL 返回给调用者。
  • { action=android.app.action.GET_CONTENT type=vnd.android.cursor.item/vnd.google.note } 上面的 action pick Intent 类似,不同的是这个 Intent 允许调用者(在这里指要调用 NotesList 的某个 Activity )指定 它们需要返回的数据类型,系统会根据这个数据类型查找合适的 Activity (在这里系统会找到 NotesList 这个 Activity ),供用户选择便笺。


       
第二个 Activity com.google.android.notepad.NoteEditor ,它为用户显示一条便笺,并且允许 用户修改这个便笺。它定义了两个 intent-filter ,所以具有两个功能。第一个功能是,当数据类型为 vnd.android.cursor.item/vnd.google.note 时,允许用户查看和修改一个便签( action android.app.action.VIEW android.app.action.EDIT )。第二个功能是,当数据类型为 vnd.android.cursor.dir/vnd.google.note ,为调用者显示一个新建便笺的界面,并将新建的便笺插 入到便笺列表中( action android.app.action.INSERT )。

      有了这两个功能,下面的 Intent 就会被解析到 NoteEditor 这个 activity

  • { action=android.app.action.VIEW data=content://com.google.provider.NotePad/notes/{ID} } 向用户显示标识为 ID 的便笺。
  • { action=android.app.action.EDIT data=content://com.google.provider.NotePad/notes/{ID} } 允许用户编辑标识为 ID 的便笺。
  • { action=android.app.action.INSERT data=content://com.google.provider.NotePad/notes } 在“ content://com.google.provider.NotePad/notes 这个便笺列表中创建一个新的空便笺,并允许用 户编辑这个便签。当用户保存这个便笺后,这个新便笺的 URI 将会返回给调用者。


       
最后一个 Activity com.google.android.notepad.TitleEditor ,它允许用户编辑便笺的标题。它可以被实现为 一个应用可以直接调用(在 Intent 中明确设置 component 属性)的类,不过这里我们将为你提供一个在现有的数据上发布可选操作的方法。在这个 Activity 的唯一的 intent-filter 中,拥有一个私有的 action com.google.android.notepad.action.EDIT_TITLE ,表明允许用户编辑便笺的标题。和前面的 view edit 动作一样,调用这个 Intent 的时候,也必须指定具体的便笺( type vnd.android.cursor.item/vnd.google.note )。不同的是,这里显示和编 辑的只是便笺数据中的标题。
     
除了支持缺省类别( android.intent.category.DEFAULT ),标题编辑器还支持另外两个标准类别: android.intent.category.ALTERNATIVE android.intent.category.SELECTED_ALTERNATIVE 。实现了这两个类别之后,其它 Activity 就可以调用 queryIntentActivityOptions(ComponentName, Intent[], Intent, int) 查询这个 Activity 提供的 action ,而不需要了解它的具体实现;或者调用 addIntentOptions(int, int, ComponentName, Intent[], Intent, int, Menu.Item[]) 建立动态菜单。需要说明的是,在这个 intent-filter 中有一个明确的名称(通过 android:label= "@string/resolve_title" 指定),在用户浏览数据的时候,如果这个 Activity 是数据的一个可选操作,指定明确的名称可以为用 户提供一个更好控制界面。
     
有了这个功能,下面的 Intent 就会被解析到 TitleEditor 这个 Activity

  • { action=com.google.android.notepad.action.EDIT_TITLE data=content://com.google.provider.NotePad/notes/{ID} } :显示并且允许用户编辑标识为 ID 的便笺的标题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值