四大组件的纽带——Intent
前面学习Activity时己经多次使用了 Intent,当一个Activity需要启动另一个Activity时, 程序并没有直接告诉系统要启动哪个Activity,而是通过Intent来表达自己的意图:需要启动哪个Activity。
Intent不仅是封装Android应用程序需要启动某个组件的“意图”,还是应用程序组件之间通信的重要媒介。本节开始来学习Intent的使用。
一、Intent介绍
Intent最常见的用途是绑定应用程序组件,并在应用程序之间进行通信。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:
1. 启动 Activity
Activity 表示应用中的一个屏幕。通过将 Intent 传递给 startActivity(),可以启动新的 Activity 实例。Intent 描述了要启动的 Activity,并携带了任何必要的数据。
如果希望在 Activity 完成后收到结果,则可以调用 startActivityForResult()。在 Activity 的 onActivityResult() 回调中,Activity 将结果作为单独的 Intent 对象接收。
2. 启动服务
Service 是一个不使用用户界面而在后台执行操作的组件。通过将 Intent 传递给 startService(),可以启动服务执行一次性操作(例如,下载文件)。Intent 描述了要启动的服务,并携带了任何必要的数据。
如果服务旨在使用客户端-服务器接口,则通过将 Intent 传递给 bindService(),可以从其他组件绑定到此服务。
3. 发送广播
广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将 Intent 传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),可以将广播传递给其他应用。
接下来通过一个表来列举Intent启动组件的常用的方法,具体如下表所示:
组件类型 |
启动方法 |
---|---|
Activity |
ØstartActivity(Intent intent)ØstartActivityForResult(Intent intent, int requestCode) |
Service |
ØComponentName startService( Intent service)Øboolean bindService(Intent service, ServiceConnection conn, int flags) |
BroadcastReceiver |
ØsendBroadcast(Intent intent)ØsendBroadcast(Intent intent, String receiverPermission)ØsendOrderedBroadcast(Intent intent. String receiverPermission, BroadcastReceiver resuItReceiver, Handler scheduler, int initialCode, String initialData,Bundle initialExtras) ØsendOrderedBroadcast(Intent intent, String receiverPermission)ØsendStickyBroadcast(Intent intent)ØsendStickyOrderedBroadcast(Intent intent,BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) |
在上表中,列举了通过Intent来开启不同组件的常用方法。需要注意的是,使用Intent开启Activity和开启Service只有两个方法,而开启BroadcastReceiver有多个方法。
二、Intent类型
Android中Intent寻找目标组件的方式分为两种,一种是显式Intent,另一种是隐式Intent。接下来分别针对这两种Intent进行详细的讲解。
01显式Intent
显式Intent,即在通过Intent启动Activity时,需要明确指定激活组件的名称。在程序中,如果需要在本应用中启动其他的Activity时,可以使用显式意图来启动Activity,其本例代码具体如下:
// 创建Intent对象
Intent intent = new Intent(this, SecondActivity.class);// 开启ActivitystartActivity(intent);
在上述示例代码中,通过Intent的构造方法来创建Intent对象。构造方法接收两个参数,第一个参数Context要求提供一个启动Activity的上下文,第二个参数Class则是指定要启动的目标Activity,通过构造方法就可以构建出Intent对象。
除了通过指定类名开启组件外,显式Intent还可以根据目标组件的包名、全路径名来指定开启组件,代码如下所示:
Intent intent = new Intent();
intent.setClassName("com.jinyu.cqkxzsxy.android.intent", "com.jinyu.cqkxzsxy.android.intent.SecondActivity");
startActivity(intent);
在上述实例代码中,通过setClassName(包名,类全路径名)方法指定要开启组件的包名和全路径名来启动另一个组件。
Activity类中提供了一个startActivity ( Intent intent )方法,该方法专门用于开启Activity,它接收一个Intent参数,这里将构建好的Intent传入该方法即可启动目标Activity。
使用这种方式开启的Activity,意图非常明显,因此称之为显式Intent,也叫做显式意图。
02隐式Intent
没有明确指定组件名的Intent称为隐式Intent,又叫隐式意图。Android系统会根据隐式Intent中设置的动作(action )、类别(category )、数据(Uri和数据类型)找到最合适的组件。具体代码如下所示:
<activity android:name=".SecondActivity" >
<intent-filter>
<!-- 设置action属性,需要在代码中根据所设置的name打开指定的组件 -->
<action android:name="com.jinyu.cqkxzsxy.android.intent.action.xxx" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
在上述代运中,<action>标明了当前Activity可以响应的动作为“com.jinyu.cqkxzsxy.android.intent.action.xxx”,而<category>标签则包含了一些类别信息,只有当<action>和<category>中的内容同时匹配时,Activity才会被开启。
使用隐式Intent开启Activity的示例代码如下所示:
Intent intent = new Intent();intent.setAction("com.jinyu.cqkxzsxy.android.intent.action.xxx");
startActivity(intent);
在上述代码中,Intent置顶了setAction(“com.jinyu.cqkxzsxy.android.intent.action.xxx”);这个动作并没有指定category,这是因为清单文件中配置的“android.intent.category.DEFAULT”是一种默认的category,在调用startActivity()方法时,会自动将这个category添加到Intent中。
隐式 Intent启动Activity的示意图如下图所示。
在上图中,Activity A 创建包含操作描述的 Intent,并将其传递给 startActivity()。 Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。 找到匹配项之后,该系统通过调用匹配 Activity(Activity B)的 onCreate() 方法并将其传递给 Intent,以此启动匹配 Activity。
在上述两种Intent中,显式Intent开启组件时必须要指定组件的名称,一般只在本应用程序切换组件时使用。而隐式Intent的功能要比显示Intent更加强大,不仅可以开启本应用的组件,还可以开启其他应用的组件,例如打开系统自带的照相机、浏览器等。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 动态分组卷积-Dynamic Group Convolution for Accelerating Convolutional Neural Networks
- (15)Shell概述及脚本执行方式
- jvm线上内存问题排查
- (18)Bash输入输出重定向
- RPC 和 REST还有RESTFul到底是个什么玩意?
- 线程和线程池的几个状态值
- 阿里代码规约为什么不让使用Executors包装好线程池呢?
- Groovy、热部署和热加载(自定义类加载器)及spring loaded 部分源码分析
- Centos在线迁移到腾讯云cvm
- ClickHouse源码导读:网络IO
- 手把手教你:将ClickHouse集群迁至云上
- 直播中台iLiveSDK终端框架演变之路
- ClickHouse 数据导入实战:Kafka 篇
- pipeAsyncFunctions
- 【python-leetcode287-循环排序】寻找重复的数