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;
}
}

最新文章

  1. JS高程5.引用类型(2)Array类型
  2. 玩转Jquery,告别前端知道思路忘记知识点的痛苦
  3. Sikuli图形脚本测试工具安装及介绍(适合小白的测试神器)
  4. 微信app支付,服务端对接
  5. IOS基础之 (一) OC基础语法
  6. Apache OFBiz 学习笔记 之 实体引擎
  7. lnmp全面优化集合nginx+mysql+php
  8. Jsp中三种注释
  9. uva 11732 - strcmp() Anyone? 不错的Trie题
  10. 典型的团队VS优秀团队
  11. android堆栈调试--详细
  12. 【转】Python+opencv利用sobel进行边缘检测(细节讲解)
  13. .net反编译的九款神器(转载)
  14. JavaScript之DOM等级概述
  15. RHEL7或CentOS7安装11.2.0.4 RAC碰到的问题
  16. 【Visual Studio】Visual C# 中XML注释的使用(含注释在开发时显示换行)
  17. linux系统负载
  18. 用newLISP通过SMTPserver发送邮件
  19. Android 让GridView的高度为Wrap_content根据内容自适应高度
  20. Spark源码分析 – Dependency

热门文章

  1. bzoj 5329 战略游戏
  2. Java语法基础练习2
  3. 利用Redis Sentinel实现redis主从自动切换
  4. 【原创】MapReduce备份Elasticsearch数据到HDFS(JAVA)
  5. Ruby 动态生成变量
  6. Ruby Regexp类
  7. idea运行scala有问题
  8. Codeforces Round #409(Div.2)
  9. Luogu P1330 封锁阳光大学【Dfs】 By cellur925
  10. [ZJOI2011]道馆之战