Android Intent 使用及其详解

Intent这东西,在Android中的地位至关重要,甚至成为"Android第五大组件"。

在我们的常规业务开发中,各个页面的跳转,service的使用,打开相机,app内分享,广播的使用等等都必须用到它。在我们的framework层里,它的身影也随处可见。

一、什么是Intent?

Intent是Android系统用来抽象描述要执行的一个操作,也可以在不同组件之间进行沟通和消息传递。

Intent意图可以是明确的指定组件的名称,这样你可以精确的启动某个系统组件,比如启动一个Activity。它也可以是模糊的,没有指定组件名称,只要是能够匹配到这个Intent的应用都可以接收到,比如发送一个拍照Intent,所有的拍照应用都会响应。

二、Intent的分类

intent分为显式Intent和隐式Intent:

显式的Intent就是你已经知道要启动的组件名称,比如某个Activity的包名和类名,在Intent中明确的指定了这个组件(Activity),一般来说这种Intent经常用在一个应用中,因为你已经明确的知道要启动的组件名称。

隐式的Intent就是你不知道要启动的组件名称,只知道一个Intent动作要执行,比如:拍照,分享,打开相册,查看地图。一般来说这种Intent用在不同的应用之间传递信息。

当你创建一个显式Intent来启动一个Activity或者Service时,系统会立刻启动那个组件通过你的Intent对象。

当你创建一个隐式Intent,系统会根据manifest中的intent filter寻找匹配的组件,如果你发送的Intent匹配到一个intent filter,系统会把你的Intent传递给该filter对应的组件(Activity、Service等),并且启动它。如果找到多个匹配的intent filter对应的应用程序,则会弹出一个对话框让你选择哪个应用程序接受你的Intent。

三、intent的简单使用

1.跳转指定页面(显示)

 mBinding.acLockSettingIcon.setOnClickListener {startActivity(Intent(this, SettingActivity::class.java))}

2.打开网页(隐式)

 public void invokeWebBrowser(View view) {  Intent intent = new Intent(Intent.ACTION_VIEW);  intent.setData(Uri.parse("http://www.google.com"));  startActivity(intent);  
}

3.打电话(隐式)

public void call(View view) {  Intent intent = new Intent(Intent.ACTION_CALL);  intent.setData(Uri.parse("tel:110"));  startActivity(intent);  
}

4.发送短信(隐式)

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType(HTTP.PLAIN_TEXT_TYPE); // "text/plain" MIME type

5.分享图片

private void share(String content, Uri uri){Intent shareIntent = new Intent(Intent.ACTION_SEND);if(uri!=null){shareIntent.putExtra(Intent.EXTRA_STREAM, uri);shareIntent.setType("image/*");//当用户选择短信时使用sms_body取得文字shareIntent.putExtra("sms_body", content);}else{shareIntent.setType("text/plain");}shareIntent.putExtra(Intent.EXTRA_TEXT, content);//自定义选择框的标题startActivity(Intent.createChooser(shareIntent, "邀请好友"));//系统默认标题}

6.打开指定应用

String package_name="xx.xx.xx";
PackageManager packageManager = context.getPackageManager();
Intent it = packageManager.getLaunchIntentForPackage(package_name);
startActivity(it);

四、Intent的属性 

在Intent里,可以配置以下属性

1.setAction:意图,一个字符串变量,用来指定Intent要执行的动作类别

2.setData:一个Uri对象,对应着一个数据,这个数据可能是MIME类型的。当创建一个intent时,除了要指定数据的URI之外,指定数据的类型(MIME type)也很重要,它能够帮助系统找到最合适的那个系统组件来处理你的intent请求。然而,MIME type有时能够通过URI来推测出来,特别是当data是content:的URI,这样的data表明在设备中由ContentProvider提供。

只设置数据的URI可以调用setData()方法,只设置MIME类型可以调用setType()方法,如果要同时设置这两个可以调用setDataAndType()。

3.Category:一个包含Intent额外信息的字符串,表示哪种类型的组件来处理这个Intent.

例如:

        <receiverandroid:name=".receiver.BootBroadcastReceiver"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></receiver>
  • CATEGORY_LAUNCHER:表示这个Activity是Activity栈最初的Activity,应用程序的主Activity,可以在桌面应用程序列表找到并启动它。
  • 这个receiver监听 Android手机开机后,会发送android.intent.action.BOOT_COMPLETED广播,监听这个广播就能监听开机。
  • 当然,我在动态注册广播的时候,也可以通过
    private void registerListener() {if (mContext != null) {IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_ON);filter.addAction(Intent.ACTION_SCREEN_OFF);filter.addAction(Intent.ACTION_USER_PRESENT);filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);//home键mContext.registerReceiver(mScreenReceiver, filter);}

    这样去监听锁屏/熄屏/home键等操作

以上Intent的属性(component name、action、data and category)都是Intent的特征属性,通过这些属性Android系统可以找到哪个应用组件将会被启动。

还有以下属性:

1.Extras:Intent可以携带的额外key-value数据,你可以通过调用putExtra()方法设置数据,每一个key对应一个value数据。你也可以通过创建Bundle对象来存储所有数据,然后通过调用putExtras()方法来设置数据。对于数据key的名字要尽量用包名做前缀,然后再加上其他,这样来保证key的唯一性。

2.Flags:用来指示系统如何启动一个Activity(比如:这个Activity属于哪个Activity栈)和Activity启动后如何处理它(比如:是否把这个Activity归为最近的活动列表中)。例如我在点击通知栏的im信息后,我把flag设置为FLAG_ACTIVITY_CLEAR_TOP,那么在该activity之上的activity都会关闭,并且intent会传递给老的activity(现在在栈顶),设置为FLAG.ACTIVITY_NEW_TASK 标志主要用于确保当从一个非 Activity 类型的 Context(例如,一个 Service 或 Application)启动 Activity 时,该 Activity 会被放置在一个新的任务(task)栈中。

上面就是Intent的一些基本使用和介绍

五、Intent传递数据

在常规的开发中,我们通常会使用Intent传递一些简单的数据。如果数据过大,就会爆TransactionTooLargeException异常。

简单来说,Intent 传输数据的机制中,用到了 Binder。Intent 中的数据,会作为 Parcel 被存储在 Binder 的事务缓冲区(Binder transaction buffer)中的对象进行传输。而这个 Binder 事务缓冲区具有一个有限的固定大小,当前为 1MB。你可别以为传递 1MB 以下的数据就安全了,这里的 1MB 空间并不是当前操作独享的,而是由当前进程所共享。也就是说 Intent 在 Activity 间传输数据,本身也不适合传递太大的数据。

在Intent的数据传输中:使用 Bundle 存储数据,是用的值传递(深拷贝),Intent 传输的数据,都存放在一个 Bundle 类型的对象 mExtras 中,Bundle 要求所有存储的数据,都是可被序列化的。在 Android 中,序列化数据需要实现 Serializable 或者 Parcelable。对于基础数据类型的包装类,本身就是实现了 Serializable,而我们自定义的对象,按需实现这两个序列化接口的其中一个即可。

为什么用的深拷贝?因为在Activity 之间传递数据,首先要考虑跨进程的问题,而 Android 中又是通过 Binder 机制来解决跨进程通信的问题。所以说这个传递数据的大小和binder传输数据相关。

所以:

  • Intent 无法传递大数据是因为其内部使用了 Binder 通信机制,Binder 事务缓冲区限制了传递数据的大小。
  • Binder 事务缓冲区的大小限定在 1MB,但是这个尺寸是共享的,也就是并不是传递 1MB 以下的数据就绝对安全,要视当前的环境而定。
  • 不要挑战 Intent 传递数据大小的极限,对于大数据,例如长字符串、Bitmap 等,不要考虑 Intent 传递数据的方案。

其他的tips:

Intent传递数据和Bundle传递数据是一回事,Intent传递时内部还是调用了Bundle。

Bundle只是一个信息的载体,内部其实就是维护了一个Map<String,Object>。Intent负责Activity之间的交互,内部是持有一个Bundle的。但是我们不能直接传递Map对象哦。

六、PendingIntent

  • 从字面意思上理解,PendingIntent 是一种延迟的 Intent,表示一种延迟执行的意图操作。

    PendingIntent 的应用场景关键在于间接的 Intent 跳转需求, 即先通过一级 Intent 跳转到某个组件,在该组件完成任务后再间接地跳转到二级的 Intent。PendingIntent 中的单词 “pending” 指延迟或挂起,就是指它是延迟的或挂起的。例如,你在以下场景中就可以使用 PendingIntent:

    • 场景 1 - 系统通知消息的点击操作(例如im消息跳转)
    • 场景 2 - 桌面微件的点击操作
    • 场景 3 - 系统闹钟操作
    • 场景 4 - 第三方应用回调操作

在这些场景中,我们真正感兴趣的操作是挂起的,并且该操作并不是由当前应用执行,而是由某个外部应用来 “间接” 执行的。例如,我们在发送系统通知消息时,会通过 PendingIntent 构造一个系统通知 Notification ,并调用 NotificationManagerCompat.notify(…) 发送通知,此时并不会直接执行 PendingIntent。而是当系统显示通知,并且用户点击通知时,才会由系统通知这个系统应用间接执行 PendingIntent#send() ,而不是通过当前应用执行。

1. PendingIntent 和 Intent 的区别

1、执行进程不同 —— PendingIntent 在其他进程执行: Intent 通常会在创建进程中执行,而 PendingIntent 通常不会在创建进程中执行;

2、执行时间不同 —— PendingIntent 会延迟执行: Intent 通常会立即执行,而 PendingIntent 通常会延迟执行,延迟到其他进程完成任务后再执行,甚至延迟到创建进程消亡后。例如,在 场景 1 - 系统通知消息的点击操作 中,即使发送系统通知消息的进程已经消亡了,依然不妨碍二级 Intent 的跳转;

3、执行身份不同 —— PendingIntent 支持授权: PendingIntent 内部持有授权信息,支持其他应用以当前应用的身份执行,这有利于避免嵌套 Intent 存在的安全隐患。而直接使用 Intent 的话,一般只能以当前应用的身份执行(为什么说一般?因为有 Activity#startActivityAsUser() 这个 API,但一般你拿不到所需的参数)。

2.PendingIntent 的使用方法

// 启动 Activity
PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)
// 启动 Service
PendingIntent.Service(Context context, int requestCode, Intent intent, int flags)
// 启动 BroadcastReceiver(发送广播)
PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags)

PendingIntent 的 4 个参数:

1、context: 当前应用的上下文,PendingIntent 将从中抽取授权信息;

2、requestCode: PendingIntent 的请求码,与 Intent 的请求码类似;

3、intent: 最终的意图操作;

4、flag: 控制标记位,通过标记位 FLAG_MUTABLE 和 FLAG_IMMUTABLE 控制 PendingIntent 可变或不可变。可变性意味着在消费 PendingIntent 时,可以针对其中包装的 Intent 进行修改,即使用 PendingIntent#send(Context, int, Intent) 进行修改。需要注意的是,这里的 Intent 参数并不会完全替换 PendingIntent 中包装的 Intent,而是将修改的信息填充到原有的 Intent 上。FLAG_UPDATE_CURRENT: 更新标记位 1,如果系统中已经存在相同的 PendingIntent,那么将保留原有 PendingIntent 对象,而更新其中的 Intent。即使不可变 PendingIntent,依然可以在当前应用更新;FLAG_CANCEL_CURRENT: 更新标记位 2,如果系统中已经存在相同的 PendingIntent,那么将先取消原有的 PendingIntent,并重新创建新的 PendingIntent。: 更新标记位 3,如果系统中已经存在相同的 PendingIntent,那么不会重新创建,而是直接返回 null;

FLAG_ONE_SHOT: 一次有效标记位,PendingIntent 被消费后不支持重复消费,即只能使用一次。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18354.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构之堆(优先级队列)

前言 在上一章我们讲了二叉树&#xff0c;这一节我们来讲堆&#xff08;优先级队列&#xff09;&#xff0c;所以想知道堆创建&#xff0c;可以看一下二叉树的一些简单概念。http://t.csdnimg.cn/4jUR6http://t.csdnimg.cn/4jUR6 目录 前言 堆 1.概念 2.优先级队列的模拟实…

Jetson Nano重装支持cuda和aruco库的opencv-4.1.1和opencv_contrib-4.1.1【2024亲测可用】

前言 在宇树四足机器狗开发过程中&#xff0c;可能会碰到无法调用aruco库实现二维码检测&#xff0c;这是因为没有安装opencv_contrib库&#xff0c;安装opencv_contrib库需要卸载现有的opencv&#xff0c;然后重新安装&#xff0c;本文就是记录这个过程&#xff0c;亲测有效。…

1.2数学基础

向量运算 矩阵运算 比较基础就不记录了 MVP矩阵推导 1.讲为什么要有矩阵变换和不同的坐标空间 将3D物体转化到2D平面为各个空间的运用做准备 2.介绍各个空间的概念和含义 MVP矩阵代表什么&#xff1f; MVP矩阵分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。…

positivessl泛域名证书500元13个月

随着创建网站的门槛变低&#xff0c;不论是个人用户还是企事业单位用户创建的域名网站也越来越多&#xff0c;怎么维护网络环境的安全成为了各个用户需要解决的问题。为了保护网站的数据安全&#xff0c;防止恶意攻击和数据泄露&#xff0c;大多数用户选择为域名网站安装数字证…

linux 创建网络端口监听

1.nc nc命令全程netcat&#xff0c;用于设置路由器。他能通过TCP和UDP在网络中读写数据。 启动一个监听的端口 nc -l -p <port_number> 范围端口扫描(默认TCP) nc -v -z -w2 127.0.0.1 1-10000UDP范围端口扫描 nc -v -u -z -w2 127.0.0.1 1-10000指定端口扫描 nc -nvv 12…

NGINX启动停止与各种常见问题

很多项目代理工具都是NGINX&#xff0c;这个工具也确实很牛。据说是俄罗斯人研发出来的。 NGINX的配置文件通常是../xx/conf/nginx.conf&#xff0c;在里面做后端服务器IP或者网关IP的代理&#xff0c;加载前端页面的同时&#xff0c;获取后端数据。 NGINX的启动文件在../xx/…

水电智能抄表是什么?

1.简述&#xff1a;水电智能抄表的兴起 水电智能抄表系统是现代科学技术和传统公共文化服务相结合的产物&#xff0c;它通过自动化技术性改变了传统的人工抄表方式&#xff0c;大大提高了高效率&#xff0c;降低生产成本&#xff0c;同时也为用户提供了更为贴心的服务。这一新…

轻兔推荐 —— 一个好用的软件服务推荐平台

给大家推荐一个好用的的软件服务推荐平台&#xff1a;轻兔推荐 网站界面简洁大方&#xff0c;没有太多杂七杂八的功能和页面&#xff0c;有明暗主题色可以选择&#xff0c;默认为亮色&#xff0c;可在网站上方手动切换。 每工作日都会推荐一款软件&#xff0c;有时会加更&…

B2124 判断字符串是否为回文

判断字符串是否为回文 题目描述 输入一个字符串&#xff0c;输出该字符串是否回文。回文是指顺读和倒读都一样的字符串。 输入格式 输入一行字符串&#xff0c;长度小于 100 100 100。 输出格式 如果字符串是回文&#xff0c;输出 yes&#xff1b;否则&#xff0c;输出 …

Flutter 中的 PhysicalModel 小部件:全面指南

Flutter 中的 PhysicalModel 小部件&#xff1a;全面指南 Flutter 的 PhysicalModel 小部件提供了一种简单而高效的方式来给应用添加物理效果&#xff0c;如阴影和层次感。它本质上是一个矩形的 Container&#xff0c;带有圆角边框和可选的阴影&#xff0c;能够模仿真实世界中…

数据赋能(102)——概念:数据分析、数据挖掘、数据洞察

此文为本人学习与提高能力的笔记。 数据分析、数据挖掘与数据洞察这三个术语&#xff0c;为了确保这些术语使用的精准度和专业性&#xff0c;我们必须对它们有更为深入的认知。这三个概念虽在某种程度上相互关联&#xff0c;但在实际应用中各自承载着不同的侧重点和用途&#…

内网安全--隧道技术-MSF上线本地

免责声明:本文仅做技术交流与学习... 不得不说,小白最近也是用上了viper,这里要特别感谢一下my bro 北岭敲键盘的荒漠猫 MSF--viper: --生成马子-->上线 --进入meterpreter. 1-查看路由,添加路由. 查看路由信息 : run autoroute -p run post/multi/manage/autoroute 添加…

『香橙派』基于Orange Pi AIpro打造高效个人云存储解决方案

&#x1f4e3;读完这篇文章里你能收获到 了解Orange Pi AIpro硬件优势&#xff0c;为构建高效云存储基础设施的理想平台。学会使用Orange Pi AIpro硬件平台&#xff0c;搭载Ubuntu Server系统&#xff0c;打造云存储环境。掌握利用Kodbox软件&#xff0c;享受文件管理、多格式…

微软MSBuild大会发布Copilot+PC:技术革新还是隐私噩梦?

微软在最近的MSBuild 2024大会上发布了全新的CopilotPC概念&#xff0c;这一技术结合了高通骁龙X Elite芯片&#xff0c;将人工智能与PC紧密结合。此次发布引起了广泛关注&#xff0c;不仅是因为其技术创新&#xff0c;还因为潜在的隐私问题。甚至连Elon Musk也对此表示担忧&am…

CGAL 网格布尔操作(带属性)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 CGAL在进行布尔操作时可以为我们提供了Mesh的相关信息,比如并集部分是由原Mesh数据的那些面片组成,虽然现阶段还不了解这有什么用。 二、实现代码 #include <iostream> #include <iterator> #includ…

小熊家务帮day5 客户管理模块1 (小程序认证,手机验证码认证等)

客户管理模块 1.认证模块1.1 认证方式介绍1.1.1 小程序认证1.1.2 手机验证码登录1.1.3 账号密码认证 1.2 小程序认证1.2.1 小程序申请1.2.2 创建客户后端工程jzo2o-customer1.2.3 开发部署前端1.2.4 小程序认证流程1.2.4.1 customer小程序认证接口设计Controller层Service层调用…

C++ | Leetcode C++题解之第118题杨辉三角

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> generate(int numRows) {vector<vector<int>> ret(numRows);for (int i 0; i < numRows; i) {ret[i].resize(i 1);ret[i][0] ret[i][i] 1;for (int j 1; j &…

Python | Leetcode Python题解之第117题填充每个节点的下一个右侧节点指针II

题目&#xff1a; 题解&#xff1a; class Solution:def connect(self, root: Node) -> Node:if not root:return Nonestart rootwhile start:self.last Noneself.nextStart Nonep startwhile p:if p.left:self.handle(p.left)if p.right:self.handle(p.right)p p.nex…

基于眼底增强的疾病感知蒸馏模型用于OCT图像的视网膜疾病分类

文章目录 Fundus-Enhanced Disease-Aware Distillation Model for Retinal Disease Classification from OCT Images摘要方法实验结果 Fundus-Enhanced Disease-Aware Distillation Model for Retinal Disease Classification from OCT Images 摘要 光学相干断层扫描&#xf…

【MySQL】SQL 基础

文章目录 【 1. SQL 的书写规则 】1.1 大小写规则1.2 常量的表示1.3 注释1.4 HELP 系统帮助 【 2. 常用数据库函数 】2.1 SHOW DATABASES 显示数据库2.2 CREATE DATABASE 创建数据库2.3 ALTER DATABASE 修改数据库2.4 DROP DATABASE 删除数据库2.5 USE 选择数据库 【 3. RDBMS …