• Android必须弄懂的基础概念:Context

    必知必会
    服务器君一共花费 16.674 ms 进行了 2 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    在android中我们经常遇到这样的情况,在创建一个对象的时候往往需要传递一个this参数,比如:语句 MyView mView = new MyView(this),要求传递一个this参数,这个this究竟指的是什么东西呢?其实这里的this指的就是当前的Activity.this,是这个语句所在的Activity的this。Activity.this取的是这个Activity的Context。

    又比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用this时就会报错,所以我们可能使用ActivityName.this来解决。

    说了这么多,那么这个Context究竟是什么东西呢?它起到什么作用呢?

    Context 按照英文字面意思就是"上下文",它位于位于framework package的android.content.Context中,其实该类为LONG型,类似于句柄。很多方法需要通过 Context才能识别调用者的实例。

    SDK中对其说明如下:

    Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc

    Context,如果是直接从文档翻译过来,就真的是十足的专业了:提供应用环境全局信息的接口,并且这个接口是由抽象类实现的,它的执行被android系统所提供,允许我们获取以应用为特征的资源和类型,同时启动应用级的操作,如启动Activity,broadcasting和接收intent。

    从上面描述可知三点,即:

    1. 它描述的是一个应用程序环境的信息,即上下文。
    2. 该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
    3. 通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息 等。

    于是,我们可以利用该Context对象去构建应用级别操作(application-level operations) 。

    Context继承关系如下:

    1. Context类

    路径: /frameworks/base/core/java/android/content/Context.java

    说明: 抽象类,提供了一组通用的API。

    public abstract class Context {  
         ...  
         public abstract Object getSystemService(String name);  //获得系统级服务  
         public abstract void startActivity(Intent intent);     //通过一个Intent启动Activity  
         public abstract ComponentName startService(Intent service);  //启动Service  
         //根据文件名得到SharedPreferences对象  
         public abstract SharedPreferences getSharedPreferences(String name,int mode);  
         ...  
    }
    

    2. ContextIml.java类

    路径 :/frameworks/base/core/java/android/app/ContextImpl.java

    说明:该Context类的实现类为ContextIml,该类实现了Context类的功能。请注意,该函数的大部分功能都是直接调用其属性mPackageInfo去完成,这点我们后面会讲到。

    /** 
     * Common implementation of Context API, which provides the base 
     * context object for Activity and other application components. 
     */  
    class ContextImpl extends Context{  
        //所有Application程序公用一个mPackageInfo对象  
        /*package*/ ActivityThread.PackageInfo mPackageInfo;  
          
        @Override  
        public Object getSystemService(String name){  
            ...  
            else if (ACTIVITY_SERVICE.equals(name)) {  
                return getActivityManager();  
            }   
            else if (INPUT_METHOD_SERVICE.equals(name)) {  
                return InputMethodManager.getInstance(this);  
            }  
        }   
        @Override  
        public void startActivity(Intent intent) {  
            ...  
            //开始启动一个Activity  
            mMainThread.getInstrumentation().execStartActivity(  
                getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);  
        }  
    }  
    

    3. ContextThemeWrapper类

    路径:/frameworks/base/core/java/android/view/ContextThemeWrapper.java

    说明:该类内部包含了主题(Theme)相关的接口,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类。

    public class ContextThemeWrapper extends ContextWrapper {  
         //该属性指向一个ContextIml实例,一般在创建Application、Service、Activity时赋值  
           
         private Context mBase;  
        //mBase赋值方式同样有一下两种  
         public ContextThemeWrapper(Context base, int themeres) {  
                super(base);  
                mBase = base;  
                mThemeResource = themeres;  
         }  
      
         @Override  
         protected void attachBaseContext(Context newBase) {  
                super.attachBaseContext(newBase);  
                mBase = newBase;  
         }  
    }  
    

    Activity类 、Service类 、Application类本质上都是Context子类, 更多信息大家可以自行参考源代码进行理解。

    在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context。通常我们在各种类和方法间传递的是activity context。后面我们会慢慢逐一介绍。

    一点补充:

    • getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁。
    • Activity.this的context 返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁。
    • getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文,一般不常用。
更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [计算机算法] 从双端队列引出的卡特兰数 3 个条目
  2. [数据结构] 散列表(哈希表) 13 个条目
  3. [软件工程与项目管理] 呈现树的构建 13 个条目
  4. [数据库技术] 数据库范式篇 5 个条目
  5. [智力开发与知识管理] 整体性学习策略 9 个条目
  6. [移动开发] Android Studio里的Gradle 3 个条目
  7. [移动开发] Android View注入框架Butter Knife 3 个条目
  8. [PHP程序设计] 命令式编程范式 6 个条目
  9. [PHP程序设计] fsockopen,curl与file_get_contents 12 个条目
  10. [移动开发] Android SQLite增删查改实例(数据:魔弹之王) 2 个条目
  11. [Python程序设计] urls.py设置技巧 8 个条目
  12. [PHP程序设计] 对输入文件类型的检测 1 个条目
窗口 -- [博客]