全面理解Context
出处:http://blog.csdn.net/lmj623565791/article/details/40481055,本文出自:【张鸿洋的博客】
本文大多数内容翻译自:http://www.doubleencore.com/2013/06/context/ 我重新组织了下内容以及结构,建议大家尽可能看下原文。
1、Context概念
其实一直想写一篇关于Context的文章,但是又怕技术不如而误人子弟,于是参考了些资料,今天准备整理下写出来,如有不足,请指出,参考资料会在醒目地方标明。
Context,相信不管是第一天开发Android,还是开发Android的各种老鸟,对于Context的使用一定不陌生~~你在加载资源、启动一个新的Activity、获取系统服务、获取内部文件(夹)路径、创建View操作时等都需要Context的参与,可见Context的常见性。大家可能会问到底什么是Context,Context字面意思上下文,或者叫做场景,也就是用户与操作系统操作的一个过程,比如你打电话,场景包括电话程序对应的界面,以及隐藏在背后的数据;
但是在程序的角度Context又是什么呢?在程序的角度,我们可以有比较权威的答案,Context是个抽象类,我们可以直接通过看其类结构来说明答案:
可以看到Activity、Service、Application都是Context的子类;
也就是说,Android系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。
在仔细看一下上图:Activity、Service、Application都是继承自ContextWrapper,而ContextWrapper内部会包含一个base context,由这个base context去实现了绝大多数的方法。
先扯这么多,有能力了会从别的角度去审视Context,加油~
2、Context与ApplicationContext
看了标题,千万不要被误解,ApplicationContext并没有这个类,其实更应该叫做:Activity与Application在作为Context时的区别。嗯,的确是这样的,大家在需要Context的时候,如果是在Activity中,大多直接传个this,当在匿名内部类的时候,因为this不能用,需要写XXXActivity.this,很多哥们会偷懒,直接就来个getApplicationContext。那么大家有没有想过,XXXActivity.this和getApplicationContext的区别呢?
XXXActivity和getApplicationContext返回的肯定不是一个对象,一个是当前Activity的实例,一个是项目的Application的实例。既然区别这么明显,那么各自的使用场景肯定不同,乱使用可能会带来一些问题。
下面开始介绍在使用Context时,需要注意的问题。
3、引用的保持
大家在编写一些类时,例如工具类,可能会编写成单例的方式,这些工具类大多需要去访问资源,也就说需要Context的参与。
在这样的情况下,就需要注意Context的引用问题。
例如以下的写法:
- package com.mooc.shader.roundimageview;
- import android.content.Context;
- public class CustomManager
- {
- private static CustomManager sInstance;
- private Context mContext;
- private CustomManager(Context context)
- {
- this.mContext = context;
- }
- public static synchronized CustomManager getInstance(Context context)
- {
- if (sInstance == null)
- {
- sInstance = new CustomManager(context);
- }
- return sInstance;
- }
- //some methods
- private void someOtherMethodNeedContext()
- {
- }
- }
对于上述的单例,大家应该都不陌生(请别计较getInstance的效率问题),内部保持了一个Context的引用;
这么写是没有问题的,问题在于,这个Context哪来的我们不能确定,很大的可能性,你在某个Activity里面为了方便,直接传了个this;这样问题就来了,我们的这个类中的sInstance是一个static且强引用的,在其内部引用了一个Activity作为Context,也就是说,我们的这个Activity只要我们的项目活着,就没有办法进行内存回收。而我们的Activity的生命周期肯定没这么长,所以造成了内存泄漏。
那么,我们如何才能避免这样的问题呢?
有人会说,我们可以软引用,嗯,软引用,假如被回收了,你不怕NullPointException么。
把上述代码做下修改:
- public static synchronized CustomManager getInstance(Context context)
- {
- if (sInstance == null)
- {
- sInstance = new CustomManager(context.getApplicationContext());
- }
- return sInstance;
- }
这样,我们就解决了内存泄漏的问题,因为我们引用的是一个ApplicationContext,它的生命周期和我们的单例对象一致。
这样的话,可能有人会说,早说嘛,那我们以后都这么用不就行了,很遗憾的说,不行。上面我们已经说过,Context和Application Context的区别是很大的,也就是说,他们的应用场景(你也可以认为是能力)是不同的,并非所有Activity为Context的场景,Application Context都能搞定。
下面就开始介绍各种Context的应用场景。
4、Context的应用场景
大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:
数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。
好了,这里我们看下表格,重点看Activity和Application,可以看到,和UI相关的方法基本都不建议或者不可使用Application,并且,前三个操作基本不可能在Application中出现。实际上,只要把握住一点,凡是跟UI相关的,都应该使用Activity做为Context来处理;其他的一些操作,Service,Activity,Application等实例都可以,当然了,注意Context引用的持有,防止内存泄漏。
5、总结
好了,到此,Context的分析基本完成了,希望大家在以后的使用过程中,能够稍微考虑下,这里使用Activity合适吗?会不会造成内存泄漏?这里传入Application work吗?
由于参考内容过多,本文改为译文咯~~
郭霖 Android Context完全解析,你所不知道的Context的各种细节
(二)、Android技术精髓-理解Context [源码]
全面理解Context的更多相关文章
- Android-5 理解context
context -- 用来访问全局信息 Application用途 Application生命周期 深入理解 Context http://blog.csdn.net/z1074971432/arti ...
- Android深入理解Context(二)Activity和Service的Context创建过程
前言 上一篇文章我们学习了Context关联类和Application Context的创建过程,这一篇我们接着来学习Activity和Service的Context创建过程.需要注意的是,本篇的知识 ...
- go笔记--几个例子理解context的作用
目录 go笔记--几个例子理解context的作用 context interface 先看一个简单的例程 context的作用 contxt相关函数 go笔记--几个例子理解context的作用 经 ...
- Android源码分析-全面理解Context
前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...
- Android深入理解Context(一)Context关联类和Application Context创建过程
前言 Context也就是上下文对象,是Android较为常用的类,但是对于Context,很多人都停留在会用的阶段,这个系列会带大家从源码角度来分析Context,从而更加深入的理解它. 1.Con ...
- Android深入理解Context(三)Context完全解析
1· Context类型 我们知道,Android应用都是使用Java语言来编写的,那么大家可以思考一下,一个Android程序和一个Java程序,他们最大的区别在哪里?划分界限又是 ...
- 绝对让你理解Android中的Context
这个问题是StackOverFlow上面一个热门的问题What is Context in Android? 整理这篇文章的目的是Context确实是一个非常抽象的东西.我们在项目中随手都会用到它,但 ...
- Android基础知识—Context理解及使用
Context是Android中一个非常重要的概念,用于访问全局信息,几乎所有的基础组件都继承自 Context,理解 Context 对于学习 Android 四大基本组件非常有帮助. 1. Con ...
- 深入理解Go Context
目录 emptyCtx类型 cancelCtx类型 timerCtx类型 valueCtx类型 在Go语言并发编程中,用一个goroutine来处理一个任务,而它又会创建多个goroutine来负责不 ...
随机推荐
- 嵌入式Linux驱动学习之路(八)创建最小的根文件系统
busybox 在配置busybox,在是否选择要静态链接库时,在静态下,busybox中的工具不需要动态链接库,能够直接运行.而用户自己编写的程序如果需要动态链接库,还是依然需要有. 如果是动态链接 ...
- git的两本推荐书
1. pro git, 可以网页直接看 http://iissnan.com/progit/?spm=5176.100239.blogcont5843.18.nUJDcK 2. Git权威指南 < ...
- JavaScript打开窗口与关闭页面操作大全
JavaScript新开窗口 onClick="javascript:window.location='http://www.sowsoy.com'" JavaScript新开一个 ...
- QContester
发个福利好了(求不吐槽名字 自己做的软件,(目前)效果大概如上图- 对于我这种比较喜欢参加一些奇怪比赛的人来说还是有用的. 原理-就是在后台开七个浏览器2333 按左边的按钮会开始抓取比赛,进度可以在 ...
- php中创建和调用webservice接口示例
php中创建和调用webservice接口示例 这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservi ...
- MongoDB JAVA API Filters
Filters 该过滤器类为所有的MongoDB的查询操作静态工厂方法.每个方法返回BSON类型,又可以传递给期望一个查询过滤器的任何方法的一个实例. eq:匹配等于指定值的值.gt:匹配大于指定值的 ...
- [LINK]OpenResty
http://openresty.org/ http://www.tuicool.com/articles/M3yI3y http://www.oschina.net/question/28_6046 ...
- Cordova - 使用Cordova开发iOS应用实战3(添加Cordova控制台插件)
Cordova - 使用Cordova开发iOS应用实战3(添加Cordova控制台插件) 前文介绍了通过 Safari 的 Web检查器,可以看到控制台输出的信息.但有时这样调试代码不太方便,如果在 ...
- 教你如何调用百度编辑器ueditor的上传图片、上传文件等模块
出于兴趣爱好,前段时间自己尝试写了一个叫simple的cms,里面使用了百度ueditor编辑器,发现它的多图片上传模块很不错,用起来很方便,又可以选择已经上传好的图片.正好我又是个懒人,发现有现成的 ...
- Linux socket多进程服务器框架一
重点:socket共用方法中错误码的定义以及错误码的解析 底层辅助代码 //serhelp.h #ifndef _vxser #define _vxser #ifdef __cplusplus ext ...