在中,我们先在学会了如何使用intent在代码中唤起activity。此处作深一步地学习。
什么是Intent
intent是对一个操作处理的抽象描述。context可以在使用startActivity(intent)来launch一个actvivity,就如我们在中的处理,也是最常用的方式,将activity在我们的应用中整合;可以在通过sentBroast(intent)来广播给任何有兴趣的BroadcastReceiver,可以通过startService(intent)启动服务;可以通过bindService(Intent, ServiceConnection, int)和一个后台服务进行通信。
基本要素
intent有两个基础的要求,一是action,一是data;也即采用哪些处理动作,并提供传递给这个处理动作的数据。action是一个常量,例如ACTION_VIEW用于查看资源,ACTION_EDIT 用于编辑资源,ACTION_PICK是进行选择。data是Uri的方式。例如ACTION_DIAL content://contacts/people/1,ACTION_VIEW tel:123,ACTION_EDIT content://contacts/people/1,ACTION_VIEW content://contacts/people/等等。其中通过Android系统的桌面icon来launch的action为ACTION_MAIN是不带data。
看看Intent的构造函数之一:intent = new Intent(Intent.ACTION_SENDTO ,uri)。这是我们在中的例子,包含两个重要的信息:action(处理的动作)和data(向处理动作传递的参数)。
Intent的基本属性
我们可以在minifest.xml文件,或者代码编写中,通过intent的方法来设置属性。
category:主activity采用LAUNCHER category,这表明它将在launcher menu中显示,其他的一般使用DEFAULT或者ALTERNATIVE。看一个在manifest.xml的例子。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.commonsware.android.skeleton">
<application> <activity android:name=".Now" android:label="Now"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
相关的intent的信息在<intent-filter>中定义。intent-filter属于activity。这个例子我们在intent-filter的定义表明这是一个应用中的main activity,采用category是LAUNCHER,也即在Android的主menu中有一个icon。
可一有多个action和多个category在intent-filter中,这表明这个component,也就是这个activity可处理多种类型的intent。MIME type:指出Uri数据类型,即所需要操作的资源的类型。如果我们希望采用第三方代码提供的服务,MIME type/data是这是很好的方式。
<activity android:name=".TourViewActivity">
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.item/vnd.commonsware.tour" /> </intent-filter></activity>
这是app中的一个非主activity,他的Uri类型为vnd.android.cursor.item/vnd.commonsware.tour。
component:intent所需接收的activity的class类型,然而一般我们都不需要进行设置,Android会根据intent的信息,例如action,data/MIME type,以及catergory来自动选择所需的组建。如果这个属性设置,将强制指定,除非我们非常了解确知,或者有特殊的指定(不使用系统默认方式而采用我们的自己的处理,而我们的处理应当在我们的app内,component的名字在我们当前的app中是私有),一般不对此进行设定。
extras:通过bundle方式传递给的信息,例如传递一个email的消息内容等。
接收器Receiver
有时希望在服务中触发某些处理,而不是唤起一个activity,有些时候,唤起是有条件选择的,在条件A是唤起acivityM,在条件B时,唤起activity N。对于这些情况,可使用继承BroadcastReceiver接口来处理。
这种intent接收器是一次性的,用于接收intent,特别是这种广播方式的intent(例如广播电能不足),然后action。action通常是会launch另外的intent以此触发actvivty,服务,以及其他componment的处理逻辑。
BroadcastReceiver只有一个方法onReceive(),在manifest中添加一个receiver的方式为:<receiver android:name=".MyIntentReceiverClassName" />
BroadcastReceiver将一直alive直至执行onReceive(),执行完即生命周期结束,不会再使用。这在我们使用时要注意的,例如不要在onReceive()中有什么callback之类的处理,换而言之就是不要和service帮定,也不要用于打开一个dialog。
如果要触发long-lived的component,例如某个actvity或者service,需要receiver和这些activity同等的存活时间。这种情况,不要在Manifest中对receiver进行定义,而是在代码中。在activity的onResume()中调用registerReceiver() ,来表明对某个intent的兴趣,在onPause()中调用unregisterReceiver(),来表明不需要这些intents,因为我们不需要在pause的时候接收intent,这样可以节省开支。注意不要在Activity.onSaveInstanceState()中unregister,这样在用户通过back键返回时并不会被调用。
相关链接: