Context应该是每个入门Android开发的程序员第一个接触到的概念,它代表当前的上下文环境,可以用来实现很多功能的调用,语句如下。

//获取资源管理器对象,进而可以访问到例如 string, color 等资源
Resources resources = context.getResources(); //启动指定的Activity
context.startActivity(new Intent(this, MainActivity.class)); //获取各种系统服务
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); //获取系统文件目录
File internalDir = context.getCacheDir();
File externalDir = context.getExternalCacheDir(); //更多...

可见,正确理解Context的概念是很重要的,虽然应用开发中随处可见Context的使用,但并不是所有的Context实例都具备相同的功能,在使用上需要区别对待,否则和可能会引入问题。

Context的种类

根据Context依托的组件以及用户不同,我们可以将Context分为如下几类:

  • Application:Android应用中的默认单例类,在Activity或者Service中通过getApplication()可以获取到这个单例,通过context.getApplicationContext()可以获取到应用全局唯一的Context实例。
  • Activity/Service:这两个类都是ContextWrapper的子类,在这两个类中可以通过getBaseContext()获取到他们的Context实例,不同的Activity或者Service实例,它们的Context都是独立的,不会复用。
  • BroadcastReceiver:和Activity以及Service不同,BroadcastReceiver本身并不是Context的子类,而是在回调函数onReceive()中由Android框架传入一个Context的实例。系统传入的这个Context实例是经过功能裁剪的,它不能调用registerReceiver()以及bindService()这两个函数。
  • ContentProvider:同样的,ContentProvider也不是Context的子类,但在创建时系统会传入一个Context的实例,这样在ContentProvider中可以通过调用getContext()函数获取。如果ContentProvider和调用者处于相同的应用进程中,那么getContext()将返回应用全局唯一的Context实例。如果是其他进程调用的ContentProvider,那么ContentProvider将持有自身所在进程的Context实例。

 错误使用Context导致的内存泄漏

错误地使用Context可能会导致内存泄漏,典型的例子是在实现单例模式时使用Context,如下代码是可能会导致内存泄漏的单例实现。

public class SingleInstance{
private Context mContext;
private static SingleInstance sInstance;
private SingleInstance(Context context){
mContext = context;
}
public static SingleInstace getInstance(Context context){
if(sInstance == null){
sInstance = new SingleInstance(context);
}
return sInstance;
}
}

如果使用者调用getInstance时传入的Context是一个Activity或者Service的实例,那么在应用退出之前,由于单例一直存在,会导致对应的Activity或者Service中关联的其他View或者数据结构对象也不会被释放,从而导致内存泄漏。正确的做法是使用Application Context,因为它是应用唯一的,而且生命周期是跟应用一致的,正确的单例实现如下。

public class SingleInstance{
private Context mContext;
private static SingleInstance sInstance;
private SingleInstance(Context context){
mContext = context;
}
public static SingleInstace getInstance(Context context){
if(sInstance == null){
sInstance = new SingleInstance(context.getApplicationContext());
}
return sInstance;
}
}

正确地使用Context的更多相关文章

  1. context:component-scan标签的use-default-filters属性的作用以及原理分析

    一.背景 我们在Spring+SpringMVC+Mybatis的集成开发中,经常会遇到事务配置不起作用等问题,那么本文就来分析下出现这种问题可能的原因以及解决方式. 二.分析及原理窥探 1.项目结构 ...

  2. Android Context MODE的四种模式解析(转)

    Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中.可以使用Context ...

  3. Entity Framework教程(第二版)

    源起 很多年前刚毕业那阵写过一篇关于Entity Framework的文章,没发首页却得到100+的推荐.可能是当时Entity Framework刚刚发布介绍EF的文章比较少.一晃这么多年过去了,E ...

  4. 玩转UICollectionViewLayout

    前言: 实 现垂直方向的单列表来说,使用UITableView足以:若是需要构建横向滑动列表.gridView等直线型布局,则使用 UICollectionView+UICollectionViewF ...

  5. jetty加载spring-context容器源码分析

    带着疑问开始 web.xml的顺序问题 先拿一个最简单的spring mvc web.xml来说问题,如下图:如果我将三者的顺序倒置或是乱置,会产生什么结果呢? 启动报错?还是加载未知结果?还是毫无影 ...

  6. ASP.NET验证码生成与识别

    一般验证码页面只输出一个图片而不进行其他业务处理,所以验证码一般放在一般处理程序(httpHandler)页面中,而如果将验证码生成代码放到一般处理程序中,要将生成验证码保存在Session中,这里我 ...

  7. GPUImage学习

    1.GLProgram--加载vertex和fragment的shader. 好处是完全将shader模块的加载过程独立出来. 学习:每个函数处理一件事,且函数的粒度刚好 在glLinkProgram ...

  8. 嵌入式实时操作系统μCOS原理与实践任务控制与时间的解析

    /*************************************************************************************************** ...

  9. 面向侧面的程序设计AOP-------《三》.Net平台AOP技术概览

    本文转载自张逸:晴窗笔记 .Net平台与Java平台相比,由于它至今在服务端仍不具备与unix系统的兼容性,也不具备类似于Java平台下J2EE这样的企业级容器,使得.Net平台在大型的企业级应用上, ...

随机推荐

  1. bzoj 1014 火星人prefix —— splay+hash

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用 splay 维护字符串上不同位置的哈希值还是第一次... 具体就是每个节点作为位置 ...

  2. ie7 总结

    1 ie7 对部分属性选择器严重区分大小写 在HTML中,属性名,例如id, title之类是不区分大小写的,CSS中的选择器也应该是如此.但是IE7对属性名是严格区分大小写的! 2 关于属性选择器, ...

  3. 访问linux的mysql-没有iptables文件的情况,防火墙开启3306端口

    转自:https://blog.csdn.net/wangt_1224/article/details/45824095

  4. 开源ORM

    Farseer.net轻量级开源框架 目录 https://github.com/steden/Farseer.net ---------------------------------- SunSo ...

  5. GDI+ 加载PNG图片

    #include <GdiPlus.h>#pragma comment(lib, "GdiPlus.lib")using namespace Gdiplus; clas ...

  6. head first python /chapter7 web(python 3 转 python 2.7)

    前言 书中使用的是python3,我这里使用的是python2.7 Web 的目录树 webapp/ ├── cgi-bin │ ├── athletelist.py │ ├── athletemod ...

  7. Hdu 5407 CRB and Candies (找规律)

    题目链接: Hdu 5407 CRB and Candies 题目描述: 给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C[n][n-2],C[n][n-1],C[n][ ...

  8. urllib的高级用法

    Handler简介 我们可以把他理解为各种处理器,有专门处理登录验证的,有处理cookies的,有处理代理设置的.利用他们,我们几乎可以做到HTTP请求中的所有事情. 首先,介绍一下 urllib.r ...

  9. JAVA面试题最全集

      JAVA面试题最全集 2009-01-19 15:40 3458人阅读 评论(0) 收藏 举报 java面试ejbservletstringhashmap 一.Java基础知识1.Java有那些基 ...

  10. jmeter(十二)处理Cookie与Session

    JMeter的工作原理是: JMeter可以作为Web服务器与浏览器之间的代理网关,以便捕获浏览器的请求和Web服务器的响应,这样就很容易地生成性能测试脚本, 有了性能测试脚本,JMeter就可以通过 ...