意图(Intent)和意图过滤(Intent Filters)

android intent

Intent是一个你可以用来从其它app组件中请求一个动作(action)的消息对象,尽管intents可以用几种不同方式方便组件之间的沟通,但一般有以下几种使用案例:

启动一个活动(Activity)

一个activity代表着app中一个单独的画面,你可以通过把一个Intent传递给startActivity()方法来启动一个新的Activity实例。Intent对象描述了要启动的activity和包含了必要的数据。

如果你想当一个activity启动结束时从它那里获得数据,那就调用startActivityForResult()。之前的activity就可以在它的onActivityResult()方法中获得一个分离的Intent对象。若想获得更多信息,请查看Activities指南。

用于启动一项服务

Service是一个没有用户界面,在后台运行一些操作的组件。你可以通过传递一个Intent给startService()启动一个service用于执行一次性的操作(例如下载一个文件)。Intent对象中包含了要启动的service的描述信息和必要的数据。

如果设计为客户端/服务端式的接口,你可以通过传递Intent给bindService()从另外一个组件中绑定到service。若想获得更多信息,请查看Services指南。

用于发送广播

广播是任何app都能接收到的消息。系统会为系统事件发送不同的广播,比如当系统开机或者开始充电时。你可以发送广播给其它app,通过把Intent传递给sendBroadcast(),sendOrderedBroadcast()或者sendStickyBroadcast()。

Intent类型

一共有两种Intent:

显式的intent:它用名字指定了要启动的组件名字(完整的类名)。我们通常用显式的intent来启动你自己app中的一个组件(activity之类的),因为你知道要启动的service或者activity的名字。例如,作为对用户动作的响应,要启动一个新的activity或者一个在后台下载文件的service。

隐式的intent:并没指明一个特定的组件,而是用声明要执行的动作代替,这样就可以让其它app的组件处理这个intent。例如,如果你想在地图上显示用户的位置,你可以用一个隐式的intent请求另外一个可以显示用户在地图中位置的app。

当你创建一个显示的intent用于启动一个activity或者service时,系统会马上启动在Intent对象中指定的app组件。

当你创建一个隐式intent,安卓操作系统会通过将intent中的内容和其它app的manifest文件中的intent filters做比较来启动恰当的组件。如果intent和intent filter吻合,系统就会启动对应的组件并且将Intent对象传递过去。如果有多个intent filter符合条件,那么系统就会显示一个对话框让用户选择其中一个打开。

Intent filter是app的manifest文件中的表达式,它指定了一个组件要接收何种类型的intent。例如,为一个activity声明一个intent filter,那么其它app就可以用一种特定种类的intent直接将其启动。如果你没有为一个activity指定intent filter,那么它就只能通过显式intent启动。

注意:为了确保你的app安全,你应该总是用显式的Intent来启动一个Service,并且不要为你的Service声明任何intent filter。使用隐式的intent来启动一个service有安全风险,因为你不能肯定什么服务会对intent做出响应并启动。从安卓5.0开始,如果你用隐式的intent来bindService()系统会抛出异常。

创建一个Intent

Intent对象携带了安卓系统该启动哪个组件(比如确切的组件名或者该接收此intent的组件类型category),此外还有接收组件要用于正确执行动作需要的信息。一个Intent该包含的的主要信息如下:

组件名称

就是要启动的组件的名称(Component name),这一项是可选的,但它是声明一个显式intent的关键部分,意味着这个intent只应该发送给指定名字的app组件。如果没有组件名称,那么intent就是隐式的,系统会基于其它的intent信息判断哪个组件应该接收intent的信息。如果你需要启动自己app内的一个组件,那么你应该指定组件的名称。

提示:当你启动一个Service的时候,你该总是指定它的组建名称,否则,你无法确定什么service会对intent做出响应,用户也无法看见服务启动。

Intent里用来保存这个字段的对象叫做ComponentName,你可以用目标组件的全名指定ComponentName对象。例如:com.example.ExampleActivity。你可以通过setComponent(),setClass(),setClassName(),或者Intent构造函数来设置组件名称。

动作(Action)

一个字符串,指定要执行的通用操作。

在进行广播的情况下,Action和category可以起到过滤作用,不过一般情况下,我们应该使用系统Intent类自带或者一些框架类提供的action。