1、Context的种类

我们来Context的继承结构。(图片来自:http://blog.csdn.net/guolin_blog/article/details/47028975)

从这个类中,我们可以看到Context有三种类型:Application、Activity、Service。

另外,从上面可以轻易的看出它使用了装饰者模式,也就是说Application、Activity、Service都属于Context,而具体Context的功能则是由ContextImpl类去实现的。

2、Context的数量

从上面我们知道,Context有Application、Activity和Service三种类型,一个应用的Context数量如下:

Context数量 = Activity数量 + Service数量 + 1

3、三种类型的Context是如何创建的?

可以参考这篇文章:Android应用Context详解及源码解析

4、三种类型的Context的生命周期

(1)每个应用启动的时候首先会创建Application对象,每个应用都有一个唯一的全局Application对象,与整个应用的生命周期相同,所以Application这个Context的生命周期就是整个应用的生命周期。
(2)Activity这个Context的生命周期就是Activity的生命周期。
(3)Service这个Context的生命周期就是Service的生命周期。

5、Context的引用问题

知道上面的生命周期之后,我们需要知道这个生命周期有什么作用,在很多的地方,我们都需要传入一个Context对象,那么我们到底要传入什么样的Context呢?如果这个Context传入不当,很可能出现内存泄漏的情况,下面举个例子,我们在编写一些工具类的时候,可能会编写成单例的方式,这些工具类大多需要去访问资源,也就说需要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;      }  }

上面这种单例的写法,我们可能会经常遇到,问题在于,这个Context哪来的我们不能确定,很大的可能性,你在某个Activity里面为了方便,直接传了个this;这样问题就来了,我们的这个类中的sInstance是一个static且强引用的,在其内部引用了一个Activity作为Context,也就是说,我们的这个Activity只要我们的项目活着,就没有办法进行内存回收。而我们的Activity的生命周期肯定没这么长,所以造成了内存泄漏。

下面来对代码进行修改

public static synchronized CustomManager getInstance(Context context) {      if (sInstance == null) {          sInstance = new CustomManager(context.getApplicationContext());      }      return sInstance;  } 

这样,我们就解决了内存泄漏的问题,因为我们引用的是一个ApplicationContext,它的生命周期和我们的单例对象一致。

6、Context的应用场景

大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:

数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。

数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。

数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。

另外,ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。

参考文章:Android Context 上下文 你必须知道的一切

7、getApplication()、getApplicationContext()和getBaseContext()

(1)getApplication()与getApplicationContext()返回的都是Application对象。
(2)和getBaseContext()返回的是ContextImpl对象。

具体原因可以参考文章:

Android Context完全解析,你所不知道的Context的各种细节

Android应用Context详解及源码解析

更多相关文章

  1. java获取http:图片下载代码——android基础编
  2. android开发技术
  3. android ndk jni层访问java对象小结
  4. Android(安卓)sqlite3插入速度优化方案
  5. android生命周期总结
  6. Android中文API——TabWidget
  7. Android(安卓)开源动画框架 NineOldAndroids
  8. Android(安卓)官方架构组件(一)——Lifecycle
  9. Android面试题集锦(二)

随机推荐

  1. Android Studio 打包apk,自动追加版本号和
  2. Android(安卓)Notification
  3. Android 应用语言切换的三种方法
  4. android: 横竖屏切换总结-布局改变和数据
  5. android之五大布局
  6. 在 Android(安卓)中调用二进制可执行程序
  7. Android Location的使用
  8. 安卓巴士真诚送上营养丰富的精美Android
  9. Android屏幕适配出现的原因
  10. (五)Android线程及其消息机制