小白上手第二弹——浅析Context

来源:互联网 发布:淘宝客服差评回复 编辑:程序博客网 时间:2024/05/16 19:09

转载请注明文章出处http://blog.csdn.net/Neo___/article/details/51760151

经过一段时间的学习我感觉对Android是越来越感兴趣了,不知道你是否也是呢。Context这个东西比较抽象,虽然官方的意思是叫上下文,但是上下文又是什么呢?你可以暂且将它理解为“场景”,你在Android里面做的大多数事情都是需要一个场景来提供和支持你所需要的程序和数据,这段时间总是被Context的问题所困惑,那么我现在就以一个小白的角度去讲解Context
参考文章:http://blog.csdn.net/lmj623565791/article/details/40481055
http://blog.csdn.net/race604/article/details/9331807
http://blog.csdn.net/z1074971432/article/details/12561369

Context是什么

首先,我们先创建一个类,然后让它去继承自Context,去观察它的继承树从而了解它的本质。创建一个类点击它,然后按住F4就会显示它的继承树,如图:
这里写图片描述
从图中我们可以发现它的继承关系,并且发现了两个很眼熟的东西,Activity和Service,这也证实了为什么我们在Activity中需要传入context参数的时候,我们只需要传入一个this,因为Activity本身就是Context!准确点说,Context是个抽象类,而ContextWrapper实现了它所有的方法,然后Application、Service、ContextThemeWrapper等类又去继承了ContextWapper,而Activity又通过继承ContextThemeWrapper实现了Context,具体关系请看下图:
这里写图片描述
有能力的同学可以直接看源码,可以更加深入地了解Context的内部构造。

this和XXXActivity.this的区别

一眼看上去,this和XXXActivity.this都是this,没有什么区别,只是后者多了一个ClassName,他们的作用到底体现在哪里呢,我们常常发现,在使用this的时候往往是在Activity的本身类当中,如果使用XXXActivity.this的时候往往是在嵌入类(匿名内部类,内部类)当中,如下图所示:
这里写图片描述
这是因为嵌入类当中的this指的是嵌入类本身,而不是当前类,所以需要ClassName的引用,而当前类中的this指的就是当前类本身的Context,所以在当前类中使用context的时候,直接传this就可以了。

getActivity()和getApplicationContext()的区别

我们知道getActivity()获取的是当前Activity的Context,而getApplicationContext()获取的是Applicaiton级别的Context,他们的级别不一样,作用域也不一样,而涉及UI相关的功能的时候,只有Activity的Context能去处理,其他的Context实例都是差不多的,比如空token问题——Unable to add window(token noll is not for an application),出现这个问题是因为你在进行UI方面的操作的时候传入的context是有问题的,或者是windowManager.layoutParams中缺少参数详情参考http://blog.csdn.net/springsky_/article/details/7034339;
上面的链接是解决参数的问题,但是根本原因是因为传入的context实例不是当前Activity,如图所示:
这里写图片描述
上图是通过当前Activity获取到的Application的Activity,结果出现空token异常,如果改成getActivity()则异常消除,如果同一个问题有不同的解决办法,为什么不选这个简单的呢。

Fragment中获取Activity的Context

Fragment是个好东西,初次接触Fragment的小白肯定也和我一样激动不已,恨不能眨眼就想学会它然后投入应用,但是在应用的过程中,总是会出现这样那样的问题,比如,在Fragment和Adapter结合使用的时候在构造函数中需要传入Context参数,这个参数传什么呢?Fragment没有实现Context,所以传入this肯定是不行的,我们可以通过getActivoty()或者getApplication()方法获取Context,但是就应用性而言getActivity()是比较好的,因为在Fragment中不免会涉及UI操作,但是有时会出现空指针异常,NullPointerException,很有可能是因为你的context在onActivityCreated()的外面从而导致你的context没有获取到,如图:
这里写图片描述
上图所示才是正确的获取方式,因为Fragment的生命周期中,在Activity和Fragment的关联创建完毕之后才会调用onActivityCreated()方法,这个时候我们要想获取Activity的实例必须得在重写的这个方法中获取,否则就会出现空指针异常。

获取全局Context

有的时候可能根据我们的需求不同,我们需要获取到全局Context,这样使用起来比较方便,那么怎么才能获取到全局Context呢,其实很简单,我们可以定制一个自己的Application泪来管理我们的一些全局状态的信息,首先我们需要创建一个MyApplication类继承自Application`public class MyApplication extends Application {
private static Context context;

public MyApplication()  {    // TODO Auto-generated constructor stub }@Overridepublic void onCreate() {    // TODO Auto-generated method stub    context = getApplicationContext();}public static Context getContext(){    return context;}

}`
我们只需重写父类的onCreate()方法,并通过调用getApplicationContext()方法得到了一个Application级别的Context,然后写入一个getContext()将获取到的Context返回。然后我们需要告知系统程序启动的时候需要初始化MyApplication类,只需要在AndroidManifast的application标签下写入:name=”包名.MyApplication“就可以了,这样我们就实现了一种全局获取Context的机制,之后不管你想在项目的任何地方使用Context,只需要调用一下MyApplicaiton.getApplication()方法就可以了。

最后,祝大家学习进步!在Android的道路上越走越远!

0 0
原创粉丝点击