【Android】Intent介绍及Intent在Activity中的使用方法

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

本篇博文主要介绍Intent的相关概念,以及Intent在Activity中的使用方法。

 

1.Intent的实现过程

  在Android中,Intent不仅可用于应用程序之间的交互,也可用于应用程序内部的Activity/Service之间的交互。

  Intent负责对应用中一次操作进行描述,描述内容包括动作以及动作所涉及的数据,Android中的Intent机制则根据此描述,找到对应的组件,将Intent传递给该被调用组件,完成对组件的一次调用。

  这便是Intent的实现过程,可见,在Intent中提供了组件互相调用的相关信息,实现了调用者与被调用者之间的解耦。

2.Intent的应用场合

  归纳起来,Intent的应用场合主要有以下三种:

2.1启动一个Activity

  (1)Activity.startActivity(Intent intent);  //启动一个Activity

  (2)Activity.startActivityForResult(Intent intent, int requestCode);  //启动一个带请求码的Activity,当该Activity结束时将回调原Activity的onActivityResult()方法,并返回一个结果码。

2.2启动一个Service

  (1)Context.startService(Intent service); 

  (2)Context.bindService(Intent service, ServiceConnection conn, int flags); 

2.3启动一个Broadcast

  (1)sendBroadcast(Intent intent); 

     sendBroadcastAsUser(Intent intent, UserHandle user); 

  (2)sendStickyBroadcast(Intent intent); 

         sendStickyBroadcastAsUser(Intent intent, UserHandle user); 

  (3)sendOrderedBroadcast(Intent intent, String receiverPermission); 

      sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,

 BroadcastReceiver resultReceiver,Handler scheduler, int initialCode, String initialData, Bundle initialExtras); 

 

3.Intent属性设置

  Intent的属性设置包括:Action(要执行的动作)、Data(执行动作所操作的数据)、Type(显式的指定Intent的数据类型)、Category(执行动作的附加信息)、Component(指定Intent目标组件的类名称)、Extras(其它所有附加信息的集合)。    

3.1 Action(要执行的动作)

  在SDK中定义了一系列标准动作,其中的一部分如图1所示。

图1 部分标准动作

  其中,ACTION_CALL表示调用拨打电话的应用;ACTION_EDIT表示调用编辑器;ACTION_SYNC表示同步数据。

3.2 Data(执行动作所操作的数据)

  在Intent中,Data使用指向数据的URI来表示。比如,在联系人应用中,指向联系人列表的URI是content://contacts/people/。

3.3 Type(显式的指定Intent的数据类型)

  对于不同的动作,其URI数据的类型是不同的。

  通常,Intent的数据类型能够根据其数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型。

3.4 Category(执行动作的附加信息)

  Category表示执行动作的附加信息。比如,当我们想要让所执行的动作被接收后,作为顶级应用而位于其他所有应用的最上层,并可以使用附加信息LAUNCHER_CATEGORY来实现。 

3.5 Component(指定Intent目标组件的类名称)

  Component用于指定Intent目标组件的类名称。通常,Android会根据Intent 中所包含的其它属性信息(比如Action、Data/Type、Category)进行查找,并找到一个与之匹配的目标组件。但是,如果我们设置了Component属性,明确的指定了Intent目标组件的类名称,那么上述查找过程将不需要执行。 

3.6 Extras(其它所有附加信息的集合)

  使用extras可以为组件提供扩展信息。

4.Intent解析过程

  在使用Intent时,根据是否明确的指定Intent对象的接收者,而分为两种情况。一种是显式的Intent,即在构造Intent对象时就指定其接收者;另一种是隐式的Intent,即在构造Intent对象时,并不指定其接收者。

  对于显式的Intent来说,Android不需要解析Intent,因为目标组件已经很明确。对于隐式的Intent来说,Android需要对其进行解析,通过解析,将Intent映射给可以处理该Intent的Activity、Service或Broadcast。        

  Intent解析机制是通过查找注册在AndroidManifest.xml文件中的所有IntentFilter,以及IntentFilter所定义的Intent,找到最匹配的Intent。

  在解析过程中,Android通过判断Intent的Action、Type、Category这三个属性,从而找出最匹配的Intent,具体的判断方法如下:

  (1)如果Intent指明了Action,则目标组件IntentFilter的Action列表中就必须包含有这个Action,否则不能匹配;

  (2)如果Intent没有提供Type,系统将从Data中得到数据类型。目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

  (3)如果Intent中的数据不是content: URI,而且Intent也没有明确指定它的Type,将根据Intent中数据的scheme (比如 http: 或者mailto:) 进行匹配。同理,Intent 的scheme必须出现在目标组件的scheme列表中,否则不能匹配。

  (4)如果Intent指定了一个或多个Category,这些类别必须全部出现在目标组件的类别列表中,否则不能匹配。

 

5.Intent使用实例

  下面介绍几个使用Intent的实例。

5.1调用其他的应用

  通过Intent可以调用并启动别的应用程序,比如调用拨打电话的程序,便可以使用如下的方法来完成:

复制代码
 1   /*
 2   * Function :  调用拨打电话的程序
 3   * Author   :  博客园-依旧淡然
 4   */
 5   public void intentDemo_Call() {
 6       Intent intent_call = new Intent();                //创建一个意图
 7       intent_call.setAction(Intent.ACTION_CALL);        //设置意图为打电话
 8       intent_call.setData(Uri.parse("tel:110"));        //设置电话号码
 9       startActivity(intent_call);                       //启动意图
10   }
复制代码

  当然了,因为这里使用到了打电话的功能,我们还需要在AndroidManifest.xml文件中,添加申请打电话的资源权限,具体实现方法如下:

1   <!-- 打电话的权限 -->
2     <uses-permission 
      android:name="android.permission.CALL_PHONE" />

  有关Android中的权限请求可以参阅《Android数据手册02:android.permission权限请求汇总》。

5.2跳转到另一个Activity

  通过使用Intent不仅可以调用别的应用程序,还可以实现应用程序内部之间Activity的跳转。比如如下的代码便实现了从MainActivity跳转到SecondaryActivity,并向SecondaryActivity中传递了两个数据name和age。

复制代码
 1     /*
 2      * Function  :  跳转到SecondaryActivity 
 3      * Author    :  博客园-依旧淡然
 4      */
 5     public void intentDemo_GoToSecondaryActivity() {
 6         Intent intent_toSecondary = new Intent();                      //创建一个意图
 7         intent_toSecondary.setClass(this, SecondaryActivity.class);    //指定跳转到SecondaryActivity
 8         intent_toSecondary.putExtra("name", "jack");                   //设置传递内容name
 9         intent_toSecondary.putExtra("age", 23);                        //设置传递内容age
10         startActivity(intent_toSecondary);                             //启动意图
11     }
复制代码

  那么,如何在SecondaryActivity中接收从MainActivity中传过来的内容(name、age)呢?下面的代码给出了一种实现方案。

复制代码
 1   /*
 2      * Function  :  接收mainActivity中的intent_toSecondary
 3      * Author    :  博客园-依旧淡然
 4      */
 5     public void acceptIntent() {
 6         Intent intent_accept = getIntent();           //创建一个接收意图
 7         Bundle bundle = intent_accept.getExtras();    //创建Bundle对象,用于接收Intent数据
 8         String name = bundle.getString("name");       //获取Intent的内容name
 9         int age = bundle.getInt("age");               //获取Intent的内容age
10     }
复制代码

5.3发送一个带回调方法的意图

  有时,我们可能需要通过定义在MainActivity中的某一控件来启动SecondaryActivity,并且当SecondaryActivity结束时,返给MainActivity一个执行结果。

  要实现上述的功能,只需要完成以下三步骤即可。

  (1)在MainActivity中实现向SecondaryActivity发送带请求码的意图,具体实现方法如下:

复制代码
1   /*
2      * Function  :  向SecondaryActivity发送带请求码的意图
3      * Author    :  博客园-依旧淡然
4      */
5     public void intentDemo_request() {
6         Intent intent_request = new Intent();                      //创建一个意图
7         intent_request.setClass(this, SecondaryActivity.class);    //指定跳转到SecondaryActivity
8         startActivityForResult(intent_request, REQUEST_CODE);      //启动带请求码意图
9     }
复制代码

  (2)在SecondaryActivity中接收intent_request,并向意图中填充要返给MainActivity的内容,最后还需要设置一个返回码。具体的实现方法如下:

复制代码
 1   /*
 2      * Function  :  接收mainActivity中的intent_request并返回一个结果码
 3      * Author    :  博客园-依旧淡然 
 4      */
 5     public void acceptIntentAndReturn() {
 6         Intent intent = getIntent();                           //创建一个接收意图
 7         intent.putExtra("back", "data of SecondaryActivity");  //设置意图的内容
 8         setResult(RESULT_CODE, intent);                        //设置结果码
 9         finish();                                              //结束SecondaryActivity,并返回MainActivity
10     }
复制代码

  (3)当结束SecondaryActivity时,程序将返回到MainActivity界面。此时,MainActivity中的onActivityResult()方法将被回调,而我们要做的就是实现该方法。在本示例中,该方法的具体实现方法如下:

复制代码
 1   /*
 2      * Function  :  onActivityResult回调方法
 3      * Author    :  博客园-依旧淡然
 4      */
 5     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 6         if(requestCode == REQUEST_CODE && resultCode == SecondaryActivity.RESULT_CODE) {
 7             Bundle bundle = data.getExtras();
 8             String str = bundle.getString("back");
 9             Toast.makeText(this, "从SecondaryActivity的返回值为:" + str, Toast.LENGTH_LONG).show();
10         }
11     }
复制代码

  以上的代码,我们通过判断requestCode和resultCode便可以唯一的确定MainActivity中的调用者和SecondaryActivity中的被调用者,建立起了一一对应的关系。并且,我们通过Bundle对象获取了从SecondaryActivity中返回给MainActivity的内容,并通过Toast进行了输出,如图2所示。

图2 从SecondaryActivity中返回的内容

  由图2可见,从SecondaryActivity中返回的内容正是我们在SecondaryActivity中定义的字符串“data of SecondaryActivity”。

6.总结

  本篇博文主要介绍了Intent的相关概念,以及Intent在Activity中的三种使用方法。有关Intent在Service和Broadcast中的使用方法,将在后续的Service和Broadcast的学习过程中再做介绍。

 

作者: 依旧淡然
邮箱:menlsh@163.com
本文版权归作者所有,未经作者同意,严禁转载及用作商业传播,否则将追究法律责任。
相关文章
|
15天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
66 6
|
16天前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
22 3
|
16天前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
15 3
|
16天前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
13 0
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
49 4
|
25天前
|
存储 大数据 数据库
Android经典面试题之Intent传递数据大小为什么限制是1M?
在 Android 中,使用 Intent 传递数据时存在约 1MB 的大小限制,这是由于 Binder 机制的事务缓冲区限制、Intent 的设计初衷以及内存消耗和性能问题所致。推荐使用文件存储、SharedPreferences、数据库存储或 ContentProvider 等方式传递大数据。
39 0
|
3月前
|
XML Android开发 数据格式
android中两个Activity同时设定了intent-filter的category为android.intent.category.LAUNCHER,会发生什么情况?
本文通过案例分析了在Android中当两个Activity都设置了`android.intent.category.LAUNCHER`类别时,会导致它们同时在应用启动器的"所有应用"页面显示为不同的启动入口。
64 2
android中两个Activity同时设定了intent-filter的category为android.intent.category.LAUNCHER,会发生什么情况?
|
2月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
46 0
|
3月前
|
开发工具 Android开发
解决Manifest merger failed : android:exported needs to be explicitly specified for <activity>
解决Manifest merger failed : android:exported needs to be explicitly specified for <activity>
74 1
|
4月前
|
XML Android开发 数据格式
Android 中如何设置activity的启动动画,让它像dialog一样从底部往上出来
在 Android 中实现 Activity 的对话框式过渡动画:从底部滑入与从顶部滑出。需定义两个 XML 动画文件 `activity_slide_in.xml` 和 `activity_slide_out.xml`,分别控制 Activity 的进入与退出动画。使用 `overridePendingTransition` 方法在启动 (`startActivity`) 或结束 (`finish`) Activity 时应用这些动画。为了使前 Activity 保持静止,可定义 `no_animation.xml` 并在启动新 Activity 时仅设置新 Activity 的进入动画。
88 12