Android全面解析之Context机制(一) :初识Android context
什么是Context
回想一下最初学习Android开发的时候,第一用到context是什么时候?如果你跟我一样是通过郭霖的《第一行代码》来入门android,那么一般是Toast。Toast的常规用法是:
Toast.makeText(this, "我是toast", Toast.LENGTH_SHORT).show()
当初也不知道什么是Context,只知道他需要一个context类型,把activity对象传进去即可。从此context贯穿在我开发过程的方方面面,但我始终不知道这个context到底有什么用?为什么要这个对象?我们首先来看官方对于Context类的注释:
/*** Interface to global information about an application environment. This is* an abstract class whose implementation is provided by* the Android system. It* allows access to application-specific resources and classes, as well as* up-calls for application-level operations such as launching activities,* broadcasting and receiving intents, etc.*/
public abstract class Context {...}
关于应用程序环境的全局信息的接口。 这是一个抽象类,它的实现是由Android系统提供。 它允许访问特定应用的资源和类,以及向上调用应用程序级的操作,如启动活动,广播和接收Intent等
。
可以看到Context最重要的作用就是获取全局消息、访问系统资源、调用应用程序级的操作。可能对于这些作用没什么印象,想一下,如果没有context,我们如何做到以下操作:
- 弹出一个toast
- 启动一个activity
- 获取程序布局文件、drawable文件等
- 访问数据库
这些平时看似简单的操作,一旦失去了context将无法执行。这些行为都有一个共同点:需要与系统交汇。四大组件为什么配为组件,而我们的写的就只能叫做一个普通的Java类,正是因为context的这些功能让四大组件有了不一样的能力。简单来说,context是:应用程序和系统之间的桥梁,应用程序访问系统各种资源的接口。
我们一般使用context最多的是两种情景:直接调用context的方法和调用接口时需要context参数。这些行为都意味着我们需要访问系统相关的资源。
那context是从哪里来的?AMS!AMS是系统级进程,拥有访问系统级操作的权利,应用程序的启动受AMS的调控,在程序启动的过程中,AMS会把一个“凭证”通过跨进程通信给到我们的应用程序,我们的程序会把这个“凭证”封装成context,并提供一系列的接口,这样我们的程序也就可以很方便地访问系统资源了。这样的好处是:系统可以对应用程序级的操作进行调控,限制各种情景下的权限,同时也可以防止恶意攻击。
如Application类的context和Activity的context权利是不一样的,生命周期也不一样。对于想要操作系统攻击用户的程序也进行了阻止,没有获得允许的Java类没有任何权利,而Activity开放给用户也只有部分有限的权利。而我们开发者获取context的路径,也只有从activity、application等组件获取。
因而,什么是Context?Context是应用程序与系统之间沟通的桥梁,是应用程序访问系统资源的接口,同时也是系统给应用程序的一张“权限凭证”。有了context,一个Java类才可以被称之为组件。
Context家族
上一部分我们了解什么是context以及context的重要性,这一部分就来了解一下context在源码中的子类继承情况。先看一个图:
最顶层是Context抽象类
,他定义了一系列与系统交汇的接口。ContextWrapper
继承自Context,但是并没有真正实现Context中的接口,而是把接口的实现都托管给ContextImpl
,ContextImpl是Context接口的真正实现者,从AMS拿来的“凭证”也是封装到了ContextImpl中,然后赋值给ContextWrapper,这里运用到了一种模式:装饰者模式。Application
和Service
都继承自ContextWrapper,那么他们也就拥有Context的接口方法且本身即是context,方便开发者的使用。Activity
比较特殊,因为它是有界面的,所以他需要一个主题:Theme,ContextThemeWrapper
在ContextWrapper的基础上增加与主题相关的操作。
这样的设计有这样的优点:
- Activity等可以更加方便地使用context,可以把自身当成context来使用,遇到需要context的接口直接把自身传进去即可。
- 运用装饰者模式,向外屏蔽ContextImpl的内部逻辑,同时当需要更改ContextImpl的逻辑实现,ContextWrapper的逻辑几乎不需要更改。
- 更方便地扩展不同情景下的逻辑。如service和activity,情景不同,需要的接口方法也不同,但是与系统交互的接口是相同的,使用装饰者模式可以拓展出很多的功能,同时只需要把ContextImpl对象赋值进去即可。
context的分类
前面讲到Context的家族体系时,了解到他的最终实现类有:Application、Activity、Service,ContextImpl被前三者持有,是Context接口的真正实现。那么这里讨论一下这三者有什么不同,和使用时需要注意的问题。
Application
Application是全局Context,整个应用程序只有一个,他可以访问到应用程序的包信息等资源信息。获取Application的方法一般有两个:
context.getApplicationContext()
activity.getApplication()
通过context和activity都可以获取到Application,那这两个方法有什么区别?没有区别。但为什么要提供两个一样作用的方法?getApplication()
方法更加直观,但是只能在activity中调用。getApplicationContext()
适用范围更广,任意一个context对象皆可以调用此方法。
Application类的Context的特点是生命周期长,在整个应用程序运行的期间他都会存在。同时我们可以自定义Application,并在里面做一些全局的初始化操作,或者写一个静态的context供给全局获取,不需要在方法中传入context。如:
class MyApplication : Application(){// 全局contextcompanion object{lateinit var context: Context}override fun onCreate() {super.onCreate()// 做全局初始化操作RetrofitManager.init(this)context = this}
}
这样我们就可以在应用启动的时候对一些组件进行初始化,同时可以通过MyApplication.context来获取Application对象。
但是!!!请不要把Application当成工具类使用。由于Application获取的便利性,有开发者会在Application中编写一些工具方法,全局获取使用,这样是不行的。自定义Application的目的是在程序启动的时候做全局初始化工作,而不能拿来取代工具类,这严重违背谷歌设计Application的原则,也违背Java代码规范的单一职责原则。
四大组件
Activity继承自ContextThemeWrapper,是一个拥有主题的context对象。Activity常用于与UI有关的操作,如添加window等。常规使用可以直接用activity.this。
Service继承自ContextWrapper,也可以和Activity一样直接使用service.this来使用context。和activity不同的是,Service没有界面,所以也不需要主题。
ContentProvider使用的是Application的context,Broadcast使用的是activity的context,这两点在后面会进行源码分析。
BaseContext
嗯?baseContext是什么?把这个拿出来单独讲,细心的读者可能会发现activity中有一个方法:getBaseContext
。这个是ContextWrapper中的mBase对象,也就是ContextImpl,也是context接口的真正逻辑实现。
context的使用问题
使用context最重要的问题之一是注意内存泄露。不同的context的生命周期不同,Application是在应用存在的期间会一直存在,而Activity是会随着界面的销毁而销毁,如果当我们的代码长时间持有了activity的context,如静态引用或者单例类,那么会导致activity无法被释放。如下面的代码:
object MyClass {lateinit var mContext : Contextfun showToast(context : Context){mContext = context}
}
单例类在应用持续的时间都会一直存在,这样context也就会被一直被持有,activity无法被回收,导致内存泄露。
那,我们就都换成Application不就可以了,如下:
object MyClass {lateinit var mContext : Contextfun showToast(context : Context){mContext = context.applicationContext}
}
答案是:不可以。什么时候可以使用Application?不涉及UI以及启动Activity操作Activity的context是拥有主题属性的,如果使用Application来操作UI,那么会丢失自定义的主题,采用系统默认的主题。同时,有些UI操作只有Activity可以执行,如弹出dialog,这涉及到window的token问题,我在这篇文章token验证进行了详细的解答,有兴趣的读者可以去阅读一下。这也是官方对于context不同权限的设计,没有界面的context,就不应该有操作界面的权利。使用Application启动的Activity必须指定task以及标记为singleTask,因为Application是没有任务栈的,需要重新开一个新的任务栈。因此,我们需要根据不同context的不同职责来执行不同的任务。
总结
文章讲解了什么是context、context家族、已经不同的context实现类。 通过本文可以了解什么是context以及与context相关的类。那么接下来深入讲context源码相关内容.
相关文章:
Android全面解析之Context机制(一) :初识Android context
什么是Context 回想一下最初学习Android开发的时候,第一用到context是什么时候?如果你跟我一样是通过郭霖的《第一行代码》来入门android,那么一般是Toast。Toast的常规用法是: Toast.makeText(this, "我是toast", To…...
气象百科——气象监测站的介绍
气象监测站是专门用于监测和记录大气环境状态及变化规律的设施。这些站点通过安装各种观测仪器,如温度传感器、湿度传感器、气压传感器、风速风向传感器、雨量传感器以及近年来兴起的雷达水位计等,全方位、多角度地收集大气中的温度、湿度、气压、风速风…...
学懂C++(三十):高级教程——深入解析 C++ Windows API 的多线程支持
引言 在现代应用程序中,多线程编程是实现高性能和高并发任务的关键手段。Windows 操作系统为开发者提供了一套强大的 API,用于创建和管理线程、同步任务,并优化线程性能。本文将深入探讨 C 中 Windows API 的多线程支持,详细介绍线…...
苹果笔记本电脑可以玩steam游戏吗 MacBook支持玩steam游戏吗 在Steam上玩黑神话悟空3A大作 苹果Mac怎么下载steam
游戏是生活的润滑剂,越来越多的用户开始关注Mac平台上可玩的游戏。幸运的是,Steam作为最大的数字发行平台之一,提供了大量适用于Mac操作系统的游戏。无论你是喜欢策略、冒险还是射击类游戏,都能在Steam上找到适合自己Mac设备玩耍的…...
海康摄像头(测温型)桌面客户端开发分享
分享一个自己开发的用于企业特殊场景下温度监控告警的一个桌面应用。 关键功能: 1.支持海康摄像头; 2.支持多路视频预览,多通道画面选择预览,支持视频画面回放与下载; 3.支持自动探测摄像头功能,若具备…...
骑行耳机哪个品牌性价比高?精选五大畅销骑行耳机推荐!
骨传导耳机凭借不入耳佩戴更舒适、健康等特定在短时间内迅速风靡骑行圈,其独特的设计不仅让骑行者在享受音乐的同时保持对周围环境的警觉,还因其非入耳式的佩戴方式,有效避免了长时间骑行对耳朵的压迫与不适。它不仅能够激发骑行时的激情与动…...
libcurl8.9.1 上传json
在postman中 PUT----》body----》raw----》json 结构体定义: #define MAX_ARRAY_SIZE 5*1024*1024struct SMART_DATA_CACHE {char* buf;long dwTotalLen;SMART_DATA_CACHE(){dwTotalLen 0;buf nullptr;while (!buf) {try {buf new char[MAX_ARRAY_SIZE];}c…...
什么是暗水印?企业暗水印如何实施?企业保护利器
“明察秋毫之末,而不见舆薪。” 此言道出了观察之细致入微,却也隐含了信息泄露之隐忧。 在今日之数字时代,信息如潮水般汹涌,而电脑屏幕作为信息展示的重要窗口,其安全性亦成为众人关注的焦点。 当谈及监控电脑屏幕以…...
Qt 系统相关 - 文件
目录 1. 文件概述 2. 输入输出设备类 3. 文件读写类 4. 文件和目录信息类 1. 文件概述 文件操作是应用程序必不可少的部分。Qt 作为一个通用开发库,提供了跨平台的文件操作能力。 Qt 提供了很多关于文件的类,通过这些类能够对文件系统进行操作&#x…...
Android Toast居中显示方法二
Android Toast居中显示方法一请看 Android Toast设置居中显示方法一-CSDN博客 下面来讲讲第二种方法: Toast toast Toast.makeText(MainActivity.this, "my toast", Toast.LENGTH_SHORT);LinearLayout.LayoutParams layoutParams new LinearLayout.Lay…...
Vue启动时报异常 ‘error:03000086:digital envelope routines::initialization error‘
问题描述 启动Vue项目时,突发报如下异常: opensslErrorStack: [error:03000086:digital envelope routines::initialization error,error:0308010C:digital envelope routines::unsupported],library: digital envelope routines,reason: unsupported,…...
C#委托—马工教你轻松玩转委托
前言 在C#中有一个小白谈之色变的知识点叫委托,很多学了一两年C#的还不知道委托究竟是什么东西,本文就来帮你彻底解开解惑,从此委托就是小儿科! 1、委托的本质 委托也是一种类型,大家知道所有的类型一定对应一种数据…...
当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍
目录 模型生成效果展示(prompt 全公开) 如何注册 Stable Diffusion 使用 SD(dreamstudio.ai )的收费标注如何 SD 提供哪些参数可以设置 如何使用种子来改进一张作品 我用 SD 创作的图片著作权如何归属,可以拿来商…...
NPM 使用教程:从入门到精通
NPM 使用教程:从入门到精通 1. 引言 什么是 NPM? NPM (Node Package Manager) 是 JavaScript 的包管理工具,也是世界上最大的开源库生态系统。它帮助开发者轻松地管理项目的依赖、安装和分享包。NPM 与 Node.js 紧密结合,并在开…...
基于ssm+vue+uniapp的停车场小程序的设计与实现
开发语言:Java框架:ssmuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:M…...
C语言典型例题37
《C程序设计教程(第四版)——谭浩强》 例题3.5 按照按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为 60~69分,D等在60分以下,成绩的等级从键盘输入 代码: //…...
二自由度机械臂软件系统(三)ros2_control硬件底层插件
ros2_control实现了两个功能,一个是控制算法插件即控制的实现,另一个是底层插件即跟硬件通信的功能。 参考资料:https://zhuanlan.zhihu.com/p/682574842 1、创建功能包 ros2 pkg create --build-type ament_cmake robot_control_test在sr…...
24.8.9.11数据结构|链栈和队列
链栈 1、理解 实际上是一个仅在表头进行操作的单链表,头指针指向栈顶结点或头结点,以下恋栈均指带头结点的链栈. 2、 基本操作 1、定义结构:节点含有数据域和指针域 2、初始化操作:建立一个带头结点的空栈 3、取栈顶元素操作:取出栈的栈顶元…...
StarSpider:一款高效的网络爬虫框架解析与实战
文章目录 引言官网链接StarSpider 原理简介基础使用1. 添加依赖2. 编写PageProcessor3. 启动爬虫 高级使用1. 分布式抓取2. 自定义下载器3. 深度定制 优点结语 引言 在大数据时代,数据成为了推动业务增长和创新的关键。网络爬虫作为数据获取的重要手段之一…...
LVS详细解析及其NAT模式与DR模式部署(理论+实验全方位指导)
目录 1. 集群 2. 分布式系统 3. 集群与分布式的比较 4.通俗的解释 集群 分布式系统 总结 LVS(Linux Virtual Server)简介 LVS专业术语 工作原理 LVS调度算法 静态调度算法 动态调度算法 ipvsadm脑图 NAT模式集群 LVS的配置 在LVS主机内打开…...
负载均衡相关概念介绍(一)
负载均衡(Load Balance)是集群技术的一种重要应用,旨在将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,从而提高系统的并发处理能力、增加吞吐量、加强网络处理能力,并提供故障转移以…...
二叉树详解(1)
文章目录 目录1. 树的概念及结构1.1 树的相关概念1.2 树的表示1.3 树在实际中的运用(表示文件系统的目录树结构) 2. 二叉树的概念及结构2.1 概念2.2 特殊的二叉树2.3 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构…...
Spring定时任务注解
Service EnableScheduling public class xxxServiceImpl implement xxxService{Scheduled(cron "0 15 11 * * ?") // 每天的11:15执行public void reportCurrentTime() {aaa();}Scheduled(cron "0 15 17 * * ?") // 每天的17:15执行public void report…...
数据结构-绪论
学习目标: 认识数据结构的基本内容 学习内容: 了解:数据结构的研究内容掌握:数据结构的基本概念和术语了解:数据元素间的结构关系掌握:算法及算法的描述 数据结构的发展: 数据结构的发展简史 …...
Web开发:web服务器-Nginx的基础介绍(含AI文稿)
目录 一、Nginx的功能: 二、正向代理和反向代理的区别 三、Nginx负载均衡的主要功能 四、nginx安装目录下的各个文件(夹)的作用: 五、常用命令 一、Nginx的功能: 1.反向代理:例如我有三台服务器&#x…...
共享经济背景下校园、办公闲置物品交易平台-计算机毕设Java|springboot实战项目
🍊作者:计算机毕设残哥 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目、 源…...
Linux 服务器上简单配置 minio
Linux 服务器上简单配置 minio 初始化结构目录 mkdir -p /data/minio/bin mkdir -p /data/minio/conf mkdir -p /data/minio/data 下载 minio cd /data/minio/bin curl -O https://dl.min.io/server/minio/release/linux-amd64/minio 添加执行权限 chmod x minio 创建配置文件…...
TypeScript 面试题汇总
引言 TypeScript 是一种由微软开发的开源、跨平台的编程语言,它是 JavaScript 的超集,为 JavaScript 添加了静态类型系统和其他高级功能。随着 TypeScript 在前端开发领域的广泛应用,掌握 TypeScript 已经成为很多开发者必备的技能之一。本文…...
杰卡德系数
杰卡德系数(Jaccard Index 或 Jaccard Similarity Coefficient) 杰卡德系数是一种用于衡量两个集合相似度的重要指标。 从数学定义上来看,如前面所述,杰卡德系数计算公式为: J ( A , B ) ∣ A ∩ B ∣ ∣ A ∪ B ∣…...
微服务实现-sleuth+zipkin分布式链路追踪和nacos配置中心
1. sleuthzipkin分布式链路追踪 在大型系统的微服务化构建中,一个系统被拆分成了许多微服务。这些模块负责不同的功能,组合成系统,最终可以提供丰富的功能。 这种架构中,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软…...
我是做网站的 怎么才能提高业绩/全网整合营销平台
文章目录前言1、乐观锁2、悲观锁3、自旋锁4、可重入锁(递归锁)5、读写锁6、公平锁7、非公平锁8、共享锁9、独占锁10、重量级锁11、轻量级锁12、偏向锁13、分段锁14、互斥锁15、同步锁16、死锁17、锁粗化18、锁消除19、synchronized20、Lock和synchronize…...
上海公司注册网/网站排名优化培训课程
转自:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-3717.htmlAndroidSDK提供了一个强大的类Drawable,Drawable这个抽象类到底代表了什么,如何使用?Drawable是个很抽象的概念,通过简单的例子程 序来学习它&#…...
微信上wordpress/seo就业
SVG剪裁路径和遮罩jQuery幻灯片是一款基于SVG clipPath和mask遮罩元素实现的网站动画幻灯片代码特效。在线演示本地下载转载于:https://www.cnblogs.com/wwhhq/p/8283759.html...
关于电商网站规划方案/广东深圳疫情最新
SOA 的思想或者理念在国内已经是一个老课题,随着规模的扩大和国际化竞争的加剧,企业内部各部门之间信息孤岛、无法协同办公的现状已经制约公司效率的提升,制 约公司的创新与发展,因此在企业客户中就产生了一种强烈需求,…...
windows2012系统怎么建设网站/网络推广是做什么工作的
场景说明研发同事让把某个double类型字段的值四舍五入保留2位小数,mysql中round(col,2)可以实现四舍五入并且保留2位小数,但是神奇的事情发生了:发现有的四舍五入是正确的,而有的不是我们想要的结果,如下:简…...
云端做效果图的网站/维普网论文收录查询
博客中添加思维导图 1 思维导图软件 Mind Master 2 插入已经绘制好的思维导图 将思维导图导出为图片格式,再使用markdown语句插入图片...