Intent 官方解释

Intent是一个需要进行的操作的抽象描述

1.通过startActivity 可以用来启动一个Activity

2.broadcastIntent 可以发送一些Intent到注册了BroadcastReceiver的具体部件

3.通过startService(Intent)或者 bindService(Intent, ServiceConnection, int) 启动或者绑定一个后台的Service

Intent提供了一种在不同Application之间进行绑定的能力,最能体现出来的是在启动一个Activity的时候,它可以被看作Activity之间的粘合剂。它基本上是一种用来抽象action的数据结构。

Intent Structure

在一个Intent中基础的信息字段包括:

action:一个需要执行的操作,例如 ACTION_VIEWACTION_EDITACTION_MAIN,等。

data:需要被操作的数据,例如一个被保存在数据库的联系人信息,表现形式为一个Uri

一些action/data的数据对儿:

  • ACTION_VIEW content://contacts/people/1 -- 打印一个定义为1的人的信息

  • ACTION_DIAL content://contacts/people/1 -- 打开一个拨号器包含1的信息

  • ACTION_VIEW tel:123 -- 打开一个拨号器包含所给的电话号码

  • ACTION_DIAL tel:123 -- 打开一个拨号器填入所给电话号码

  • ACTION_EDIT content://contacts/people/1 -- 编辑1的个人信息

  • ACTION_VIEW content://contacts/people/ -- 打印一个联系人列表。这是一个典型的进入联系人Application顶层的例子,显示出所有联系人。选择一个特定的人去打印出来,通过一个新的Intent{ACTION_VIEW content://contacts/N} 打开一个新的activity显示个人信息。


为了这些基础属性,有大量的二级属性你可以放在Intent中:

  • category -- 给一些操作执行时需要的额外的属性。例如CATEGORY_LAUNCHER 意思是说他应该作为一个顶级的Application出现在Launcher中,CATEGORY_ALTERNATIVE 意思是说他应该包含一系列对数据的操作

  • type -- 指定一个Intent数据的具体类型。通常类型是由数据本身推断出来的。通过设置这些属性,你禁用那些推断,并指出具体的类型。

  • component -- 为Intent指定一个具体的部件名称。通常这个是根据Intent中其他的信息(the action, data/type, and categories)去匹配一个可以处理它的部件,如果这个属性被设置,那么就不需要去判断,部件被明确的指出。通过指出这些属性所有其他的Intent的属性变得可选。

  • extras -- 这是一个包含其他额外信息的Bundle。它能够为部件提供大量的信息。例如,如果我们有一个发送email的操作,我们可以包括其他的数据片段,主题、正文等。

这有一些你可以通过Intent指定这些额外的参数去定义的操作。

在Intent类中定义了许多标准的action和category constants。但是应用本身也可以定自己的Intent,这些字符串用了java标准的编码规则,为了确保唯一性,例如 ACTION_VIEW 被称为"android.intent.action.VIEW"

把action、data types、categories 和 extra data 定义为系统通过短语进行表达的语言。一个应用可以通过扩展action、types 和 categories来扩展自己的语言,或者可以在自己的Activities中更改对这些短语的使用方法。

Intent Resolution

你会用到两种Intents的基本形式

Explicit Intents 明确指出了需要运行的部件(通过 setComponent(ComponentName) orsetClass(Context, Class)),通常这种情况下不会包括一些其他的信息,只是简单地对用户与应用进行交互时launch内部的activity。

Implicit Intents 没有明确的指出部件,与之前的不同的是,它必须包含足够的信息,以此来让系统判断哪个可用的部件可以使用这个Intent

当使用Implicit Intents ,给了一个任意的Intent,我们需要知道应该怎么去处理它,这个工作是由Intent resolution线程去解决的,把Intent指向可以处理他的 ActivityBroadcastReceiver, or Service或者有时有多个activities/receivers )。

 intent resolution 机制主要解决了Intent与在包中描述的 <intent-filter>之间匹配的问题。

有三个主要的信息提供给resolution用来判断:action, type, 和 category。通过这些信息, PackageManager对每一个部件进行一次询问。最合适部件的判断是基于AndroidManifest.xml中的Intent信息:

  • The action,如果给定,必须有组件做为其句柄来列出。

  • The type 是从Intent的数据中获取到的,如果没有在Intent中给出。例如一些action,如果一个Intent中包含type(无论是明确或者是不明确的)必须有组件做为其句柄来列出。

  • 如果数据不是一个 content: URI 而且在Intent中没有明确类型, 例如 http: 或者mailto:又和Action一样,如果给定,必须有组件做为其句柄来列出
  • The categories,如果使用, 必须在activity中列出category的句柄. 更确切地说, 如果你是用 CATEGORY_LAUNCHER 和 CATEGORY_ALTERNATIVE, 然后这个部件只会解决包含这两个categories的Intent. Activities 经常需要支持CATEGORY_DEFAULT 只有那样才能被 Context.startActivity()发现.
例如,一个Note Pad简单的地应用,可以允许用户通过一个note 数据列表浏览并且查看每个单独的item,斜体的地方是你需要更改为自己包名的地方

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.notepad">
     <application android:icon="@drawable/app_notes"
             android:label="@string/app_name">

         <provider class=".NotePadProvider"
                 android:authorities="com.google.provider.NotePad" />

         <activity class=".NotesList" android:label="@string/title_notes_list">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.EDIT" />
                 <action android:name="android.intent.action.PICK" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
             </intent-filter>
             <intent-filter>
                 <action android:name="android.intent.action.GET_CONTENT" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
         </activity>

         <activity class=".NoteEditor" android:label="@string/title_note">
             <intent-filter android:label="@string/resolve_edit">
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.EDIT" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>

             <intent-filter>
                 <action android:name="android.intent.action.INSERT" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
             </intent-filter>

         </activity>

         <activity class=".TitleEditor" android:label="@string/title_edit_title"
                 android:theme="@android:style/Theme.Dialog">
             <intent-filter android:label="@string/resolve_title">
                 <action android:name="com.android.notepad.action.EDIT_TITLE" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.ALTERNATIVE" />
                 <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
         </activity>

     </application>
 </manifest>

第一个Activity com.android.notepad.NotesList,提供我们进入app的主函数入口,他可以通过三个Intent模板的描述来做三件事:

<intent-filter>
     <action android:name="android.intent.action.MAIN" />
     <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>

提供一个顶级的入口给Note Pad应用:标准的MAIN action是一个主函数入口点(在Intent中不需要一些其他的信息),LAUNCHER category说明这个入口点需要被列在application launcher

<intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <action android:name="android.intent.action.EDIT" />
     <action android:name="android.intent.action.PICK" />
     <category android:name="android.intent.category.DEFAULT" />
     <data mimeType:name="vnd.android.cursor.dir/vnd.google.note" />
 </intent-filter>
这里声明的东西是说activity可以在一个note的目录下做什么事情。支持的操作需要通过标签去声明vnd.android.cursor.dir/vnd.google.note  是一个URI用来获取我们在(vnd.android.cursor.dir)下面的note pad数据(vnd.google.note)。这个Activity允许用户去查看或者更改目录数据(通过VIEW或者EDIT的操作),或者选择一个详细的note并且返回给调用者(通过PICK操作)。注意,这里有默认提供的category:当没有明确说明部件名称时这里需要提供给Context.startActivity方法用来启动Activity

<intent-filter>
     <action android:name="android.intent.action.GET_CONTENT" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
 </intent-filter>
这个filter描述了不需要知道Intent来源而返回给调用者一个选择的note.   vnd.android.cursor.dir/vnd.google.note 是一个URI用来获取我们在(vnd.android.cursor.dir)下面的note pad数据(vnd.google.note)。GET_CONTENT就像一个PICK 动作,activity会返回给调用者一段数据。这里,然而调用者明确指出了他们想要的数据类型,而不是用户将从这得到的。

根据给定的能力,下列的Intent可以传入到这个Activity中:

  • { action=android.app.action.MAIN } 匹配所有可以当做Application顶级入口的Activity。

  • { action=android.app.action.MAIN, category=android.app.category.LAUNCHER } 一个Intent被Launcher添加在顶级列表中

  • { action=android.intent.action.VIEW data=content://com.google.provider.NotePad/notes } 打印在"content://com.google.provider.NotePad/notes"下面的所有notes,用户可以用来浏览目录。

  • { action=android.app.action.PICK data=content://com.google.provider.NotePad/notes } 打印一个在"content://com.google.provider.NotePad/notes"下面的所有notes的列表,用户可以选择一个并得到它的URL

  • { action=android.app.action.GET_CONTENT type=vnd.android.cursor.item/vnd.google.note } 很像PICK操作,但是允许调用者指定返回类型,那样系统会选择最接近的Activity去接受数据。

第二个Activity, com.android.notepad.NoteEditor,给用户展示一个note,并允许用户去修改,他能做下面描述两件事:

<intent-filter android:label="@string/resolve_edit">
     <action android:name="android.intent.action.VIEW" />
     <action android:name="android.intent.action.EDIT" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
 </intent-filter>
第一,Activity最基础的目的是让用户操作一个note,MIME type  vnd.android.cursor.item/vnd.google.note . 描述的一样。Activity允许用户去查看或者标记它,之后我们支持DEFAULT category,这样允许Activity 在没有明确指出他的部件时Launch。

<intent-filter>
     <action android:name="android.intent.action.INSERT" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
 </intent-filter>
第二个是可以通过Activity向目录中插入一个新的note。这个用来在用户创建新note时使用: INSERT 操作在note目录上执行,然后再该Activity创建新的note,之后添加到对应的content provider中去。

根据给定的能力,下列的Intent可以传入到这个Activity中:

  • { action=android.intent.action.VIEW data=content://com.google.provider.NotePad/notes/{ID} } 向用户展示出note内容 根据{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 } 创建一个新的、空的note在"content://com.google.provider.NotePad/notes"目录下,允许用户编辑,如果保存修改,新创建的URI会返回给调用者。

最后一个Activity  com.android.notepad.TitleEditor,允许用户去编辑note的标题。这样可以当做一个class而直接去调用(通过在Intent中明确设置他的部件),但是这里我们展示出你能对存在数据的一些可选操作

<intent-filter android:label="@string/resolve_title">
     <action android:name="com.android.notepad.action.EDIT_TITLE" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.ALTERNATIVE" />
     <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
     <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
 </intent-filter>

在这个Intent中,我们创建了自己的私有action叫做com.android.notepad.action.EDIT_TITLE,用来去更改一个note的标题。他必须连接上一个具体的note(data type vnd.android.cursor.item/vnd.google.note)像之前的浏览和编辑一样,但是这里浏览和编辑的标题是在note数据里面。

为了支持像之前一样支持default category,我们的标题编辑器也需要支持两个或者其他标准的categories: ALTERNATIVE and SELECTED_ALTERNATIVE。实现这些categories,允许其他人去寻找没有直接了解到的其他特殊的action,通过 queryIntentActivityOptions(ComponentName, Intent[], Intent, int) 方法, 或者经常建立动态菜单选项通过 addIntentOptions(int, int, int, ComponentName, Intent[], Intent, int, MenuItem[])。注意在Intent里面也以来一个明确的名字android:label="@string/resolve_title")用来更好控制用户看见的每个具体action对应的Activity

根据给定的能力,下列的Intent可以传入到这个TitleEditor Activity中:

{ action=com.android.notepad.action.EDIT_TITLE data=content://com.google.provider.NotePad/notes/{ID} } 打印并且允许用户去编辑note根据 {ID}.

Standard Activity Actions

这些流行的标准action Intent是用来launching activities(通常通过startActivity(Intent))。到目前为止最常用的是 ACTION_MAIN 和 ACTION_EDIT.

Standard Broadcast Actions

这些流行的标准action Intent是用来接收广播通常通过 registerReceiver(BroadcastReceiver, IntentFilter)  或者在manifest中的 <receiver>标签

Standard Categories

这些流行的标准 categories是通过addCategory(String)来进一步明确Intent

Standard Extra Data

这些流行的标准 fields是通过 putExtra(String, Bundle)来添加额外的数据。


猜你喜欢

转载自blog.csdn.net/u011414158/article/details/67632213