你真的理解 Android 中的 Context 么?
概述
在使用getContext方法的时候有没有想过,在不同的场景下,取到的Context到底有什么不同,View,Fragment,Activity和Application的getContext又究竟是怎么样?
下面来分析一下。
获取Context
DecorView
DecorView的Context是Application Context。
ActivityThread.addView -> PhoneWindow.generateDecor
一般View是从LayoutInflater类中inflate生成的,查看inflate方法,会调用rinflate
发现是入参Context,在inflate方法内赋值,其实最后就是LayoutInflater.from的参数Context。
所以结论是普通View是LayoutInflater.from的参数Context。
但是对于xml这样的布局文件里面的View又是怎么样的呢?
看一下Activity.setContentView方法的调用过程是:
Activity.setContentView -> PhoneWindow.setContentView -> LayoutInflater.inflate方法,而这个LayoutInflater是在PhoneWindow的构造方法内创建的,回到Activity.attach方法,看到构造方法的参数是Activity的Context。
于是增加一个结论,在xml中解析的View的Context属于Activity。
可能有人问,那Fragment也是吗?看一下Fragment.onCreateView中参数有LayoutInflater,跟踪一下
Fragment.onCreateView <- Fragment.performCreateView -> FragmentManagerImpl.moveToState <- Fragment.performGetLayoutInflater <- Fragment.getLayoutInflater <- FragmentHostCallback.onGetLayoutInflater
结果是用了FramgentHostCallback构造方法的参数Context
结论也是Activity的Context。
FragmentActivity
一般使用FragmentActivity.this和FragmentActivity.getContext方法取到Context,最终取到的都是Activity的Context,不再赘述。
Fragment
通过Fragment.getContext取到Context,结果是取到FragmentHostCallback.getContext也是Activity的Context。
Application
取到的是Application Context。
Applicaiton与Activity的区别
所以最终的目的是区分Application与Activity的Context有什么不同。所以看它们各自的实现,Application与Activity都继承于ContextWrapper,ContextWrapper就是包装了一下抽象类Context,在构造方法里传入Context对象,根本在于构建Application和Activity的地方。
追踪一下发现Context构建都在ContextImpl类内,Application对应createAppContext,而Activity则对应createActivityContext,都在ActivityThread中调用各自创建Context方法进行初始化。
对比ContextImpl的构建,前三个参数都一致,Activity的Context多了activityToken和classLoder,其中activityToken对应ActivityRecord类,接着调用Context.setResource方法设置Activity的配置和逻辑显示相关的信息Display。
看一下这个熟悉的错误,这个是使用Application的Context启动Activity时报的错误,这个mSourceRecord就是AcitivityRecord对象,对于Application而言为null,所以需要指定New_Task这个标志。
两者之间更重要的一个区别是:生命周期。
对于Application的Context而言,在整个应用的生命周期内都不会改变;而对于不同的Activity,其Context有可能不同,例如添加一个Dialog必须附着在Activity上,所以使用Application就会报错。
除了Application,DecorView和getApplicationContext方法会取到Application Context外,其他方法getContext都会取到Activity Context或者传入的Context。
一般来说,Application Context存在于整个应用的生命周期中,不会随场景变化而改变,所以对于打开不同的Activity,Activity Context可能存在不同,而且生命周期跟Activity的生命周期一致。
原文发布时间为:2018-11-22
本文作者:豆沙包67
本文来自云栖社区合作伙伴“安卓巴士Android开发者门户”,了解相关信息可以关注“安卓巴士Android开发者门户”。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Android短视频开发都需要什么技术?
今天我们来讲点干货,估计来看这篇帖子的人都知道短视频APP有多火,也都知道安卓系统在手机系统中占的市场份额有多大,那我就不多嘴巴拉巴拉一些行业背景了,以下我着重讲一讲Android端的短视频开发技术。 Android短视频开发,视频业务是最主要的, “视频录制”和“视频编辑”是功能板块的重中之重,今天我们要讲的就是这两个方面。 如何区分二者: 视频采集、自定义码率、美颜功能、焦点的对焦变焦、调节曝光率和前后镜头以及滤镜等功能都属于视频录制功能 而稍显复杂的视频裁剪拼接功能、动画效果、音频特效、等后期功能。统统属于视频编辑。 由浅入深,成功将“视频录制”和“视频编辑”两者区分开来后,我们接着往下看。 一、Android端短视频录制功能 视频录制:在短短的时间内完成的视频录制可是经过了大程序的,首先,是对相机画面和声音的采集,然后将采集的数据进行滤镜、降噪等自动处理处理,处理完成后进行硬件编码,最后才能生成最终的MP4文件。 由于硬件编码的优越性,这种采集方式可实现在高帧率(30fps)、高分辨率(720P)以及高码率的情况下支持低性能的手机运行。 值得一提的是短视频必备的段式拍摄再合成的...
- 下一篇
为什么RISC-V在中国岌岌可危?
正如Rick Merritt在硅谷报道的那样,中国有很多“买家”对RISC-V核心感兴趣。从理论上讲,RISC-V应该为中国工程师提供急需的公平竞争环境。但现实情况是,中国和RISC-V似乎并不兼容 ,至少目前如此。以下是五个原因:一、很难摆脱Arm的束缚。首先,大多数中国芯片供应商已经在Arm上投入了大量资金,并对此感激不尽。很难摆脱Arm的束缚。鉴于Arm公司完善的生态系统以及它为Android智能手机提供首选处理核心这一事实,为什么设计和开发Android手机芯片的本地公司会转向其他任何东西?二、RISC-V不是免费核心。RISC-V提供免费的开源指令集。但这并不意味着如果一家中国公司在RISC-V基金会上敲门,就会有大量的“免费核心”。三、开发CPU需要几个专业的设计专业知识。这些包括电子逻辑,编译器和操作系统。中国设计师需要具备现代高质量通用计算机指令集的第一手经验。四、RISC-V旨在创建一个统一的社区。在许多社区努力中,亚洲工程师往往更渴望从社区“接受”而不是“贡献”它。正如VeriSilicon首席执行官Wayne Dai所说,“中国工程师不习惯'上传'他们的想法。他们...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS关闭SELinux安全模块
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长