context详解

1、Context概念:

Context,相信不管是第一天开发Android,还是开发Android的各种老鸟,对于Context的使用一定不陌生~~你在加载资源、启动一个新的Activity、获取系统服务、获取内部文件(夹)路径、创建View操作时等都需要Context的参与,可见Context的常见性。大家可能会问到底什么是Context,Context字面意思上下文,或者叫做场景,也就是用户与操作系统操作的一个过程,比如你打电话,场景包括电话程序对应的界面,以及隐藏在背后的数据; 
Android系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。 

可以看到Activity、Service、Application都是Context的子类;
在仔细看一下上图:Activity、Service、Application都是继承自ContextWrapper,而ContextWrapper内部会包含一个base context,由这个base 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的引用问题。例如以下的写法:
 1 package com.mooc.shader.roundimageview;
 2 
 3 import android.content.Context;
 4 
 5 public class CustomManager
 6 {
 7     private static CustomManager sInstance;
 8     private Context mContext;
 9 
10     private CustomManager(Context context)
11     {
12         this.mContext = context;
13     }
14 
15     public static synchronized CustomManager getInstance(Context context)
16     {
17         if (sInstance == null)
18         {
19             sInstance = new CustomManager(context);
20         }
21         return sInstance;
22     }
23     
24     //some methods 
25     private void someOtherMethodNeedContext()
26     {
27         
28     }
29 }
View Code
对于上述的单例,大家应该都不陌生(请别计较getInstance的效率问题),内部保持了一个Context的引用;
这么写是没有问题的,问题在于,这个Context哪来的我们不能确定,很大的可能性,你在某个Activity里面为了方便,直接传了个this;这样问题就来了,我们的这个类中的sInstance是一个static且强引用的,在其内部引用了一个Activity作为Context,也就是说,我们的这个Activity只要我们的项目活着,就没有办法进行内存回收。而我们的Activity的生命周期肯定没这么长,所以造成了内存泄漏。那么,我们如何才能避免这样的问题呢?有人会说,我们可以软引用,嗯,软引用,假如被回收了,你不怕NullPointException么。把上述代码做下修改:
1 public static synchronized CustomManager getInstance(Context context)
2     {
3         if (sInstance == null)
4         {
5             sInstance = new CustomManager(context.getApplicationContext());
6         }
7         return sInstance;
8     }
View Code
这样,我们就解决了内存泄漏的问题,因为我们引用的是一个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吗?由于参考内容过多,本文改为译文咯~~

 

转载于:https://www.cnblogs.com/UniqueColor/p/4735460.html

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

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

相关文章

Unity Camera的两种模式

http://www.cnblogs.com/zhaoqingqing/p/3302484.html

mysql之group_concat函数

mysql之group_concat函数 在介绍GROUP_CONCAT之前,我们先来看看concat()函数和concat_ws()函数。 先准备一个测试数据库: mysql> select * from scores; --------------------- | id | name | score | --------------------- | 1 | zhangsan | 1…

java 图片批量上传_java实现批量上传图片,还要保证每个图片的顺序号,疑问求教!...

rt我要一次性同时上传n张照片,并且每张照片的顺序号还不一样,第一张的serialno是1,第二张是2。。一开始我做单张图片上传,代码如下RequestMapping("/picUpLoad")ResponseBodypublic Map picUpLoad(MultipartFile file, …

linux 用户创建、管理、权限分配

(1)su与sudo su:通过su可以在用户之间切换,如果超级权限用户root向普通或虚拟用户切换不需要密码,什么是权力?这就是!而普通用户切换到其它任何用户都需要密码验证; sudo: sudo扮演的角色注定了…

WebApi路由

路由分为两种模式:模板路由和特性路由。 模板路由: 模板路由是ASP.NET Web API默认提供的路由。模板路由使用前需要定义路由模板。如下面默认的路由模板: 默认路由的URL格式是api/{controller}/{id}。api代表在资源前面要带上api目录&#xf…

HW--漂亮度2(测试通过)

总结:几个函数的使用 (1) int numInteger.parseInt(str[0]); //将第一个字符串转成整形数,表示名字个数 (2) String string1str[i].toLowerCase(); //变小写都 (3) char ch[]strin…

java设计模式 组合_JAVA 设计模式 组合模式

用途组合模式 (Component)将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有唯一性。组合模式是一种结构型模式。结构图-组合模式结构图Component: 组合中的对象声明接口,在适当的情况下,实现所有类共…

项目总结SpringMVC相关

流程文字概述1、用户发送请求至前端控制器DispatcherServlet2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。4、DispatcherServlet调用Ha…

SpringBoot登录登出切面开发

阅读本文约“2.5分钟” 本文开发环境是SpringBoot2.X版本。 对于系统而言(这里多指管理系统或部分具备登录登出功能的系统),登录登出是一个类权限验证的过程,现在一般是以token进行校验,即用户输入登录信息&#xff0c…

4、Cocos2dx 3.0三,找一个小游戏开发Hello World 分析

尊重开发人员的劳动成果。转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557Hello World 分析打开新建的"findmistress"项目,能够看到项目文件是由多个代码文件及目录组成的。当中 Hello World 的代码文件直…

spring --aop(日志记录)在工程中实际使用

2019独角兽企业重金招聘Python工程师标准>>> ###1.日志切面 package com.readygo.zbhealth.common;import java.util.Arrays; import java.util.List;import org.aspectj.lang.ProceedingJoinPoint;public class LoggingAspect {public Object Around(ProceedingJoi…

java 多表分页_多表单独查询组合结果的自定义分页(java代码)

多表单独查询组合结果的自定义分页实现(java代码)一、业务需求:遇到一个业务,需要多个表进行分页查询,使用union联合查询时,速度极其缓慢,即使查询的字段添加了索引,union查询好像不走索引,因此…

Neutorn LBaaS 原理

Load Balance as a Service(LBaaS)是 Neutron 提供的一项高级网络服务。LBaaS 允许租户在自己的网络中创建和管理 load balancer。 load balancer 可以说是分布式系统中比较基础的组件。 它接收前端发来的请求,然后将请求按照某种均衡策略转发…

判断一个图中有无环路的存在

这里要引入两个概念: 1.树边:是一条未被遍历过的边,它指向一个未被访问过的点。 2.反向边:是一条未被遍历过的边,它指向一个被访问过的点。 如果图中有环路的存在,那么环路的最后一个边必然是一条反向边。 …

精选的一些《编程之美》相关资料

又要到一年的招聘季了,肯定又有很多人开始啃《编程之美》了吧。这本书从开阔视野的角度来说很好,不过限于篇幅,有的问题并没有讲清楚(甚至问题叙述模棱两可、被标榜为“鼓励同面试官交流以获得更多细节”);…

java 内置函数_java8 四大内置核心函数式接口

其他补充接口:一、Consumer:消费型接口(void accept(T t))来看一个简单得例子:1 /**2 * 消费型接口Consumer3 */4 Test5 public void test1 () {6 consumo(500, (x) -> System.out.println(x));7 }89 public void consumo (double money, …

jQuery - (JQuery datatables api 使用解读)

学习可参考&#xff1a;http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/2006942 分别导入css和js文件 <link href"~/Content/bootstrap.css" rel"stylesheet" /> <link href"~/Content/datatab…

Tomcat配置JNDI数据源

经过3个多小时的努力&#xff0c;配置JNDI数据源(主要是通过DBCP连接池)终于搞定&#xff5e;还是Tomcat官方的说明好&#xff0c;不过全是英文的&#xff0c;大概还看得懂&#xff0e;百度上那么花花绿绿的太多了&#xff0c;一个也没成功&#xff01;&#xff0e;&#xff0e…

java 线程池 固定大小_使用Executors服务在Java中创建固定大小线程池的最佳方法...

查看源代码,您将意识到&#xff1a;Executors.newFixedThreadPool(threadPoolSize);相当于&#xff1a;return new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, MILLISECONDS,new LinkedBlockingQueue());由于它不提供显式的RejectedExecutionHandler,因此使用默认…

令牌验证 token

通过令牌验证在注册中心控制权限&#xff0c;以决定要不要下发令牌给消费者&#xff0c;可以防止消费者绕过注册中心访问提供者&#xff0c;另外通过注册中心可灵活改变授权方式&#xff0c;而不需修改或升级提供者。 可以全局设置开启令牌验证&#xff1a; <!--随机token令…