深入理解 Context

转载 2016年08月31日 13:41:37
什么是Context?
想必大家都不陌生,在 Android 开发中离不开 Context 调用各种跟系统有关的 API 都必须用到 Context 。我们可以将她理解为上下文环境,大概就是里面存储一堆全局变量,这些变量在调用系统 API 时需要用到。文字始终难以表达我想说的,咱们来分析原理吧!

Context  哪里来的?
开发 Android 应用必须得有一个 Activity ,然后在你的 Activity 里面调用各种系统 API 比如,
[java] view plain copy
  1. String string = getString(R.string.app_name);  
这行代码看似简单,但是如果不让你在 Activity 中调用你该怎么获取这个 string ?
[java] view plain copy
  1. Context context;  
  2. context.getString(R.string.app_name);  
你需要一个 Context 对象,那在 Activity 中为何不需要呢?
答案是,Activity 本来就是一个 Context 他继承自 Context,你打开 Activity 可以知道他的继承顺序如下:
Activity -> ContextThemeWrapper -> ContextWrapper -> Context

Context 是一个抽象类,所有方法都没实现,ContextWrapper 实现了所有方法,但是他只是一个代理,打开源码你可以看到他是这样的:
[java] view plain copy
  1. @Override  
  2. public AssetManager getAssets() {  
  3.     return mBase.getAssets();  
  4. }  
  5.   
  6. @Override  
  7. public Resources getResources()  
  8. {  
  9.     return mBase.getResources();  
  10. }  
他仅仅调用 mBase 的方法,(这种在设计模式里叫 代理模式 Proxy ),看来我们得弄清楚这个 mBase 哪来的了!
查看源码你会发现只有2个地方设置了 mBase,
[java] view plain copy
  1. public ContextWrapper(Context base) {  
  2.     mBase = base;  
  3. }  
  4.   
  5. /** 
  6.  * Set the base context for this ContextWrapper.  All calls will then be 
  7.  * delegated to the base context.  Throws 
  8.  * IllegalStateException if a base context has already been set. 
  9.  *  
  10.  * @param base The new base context for this wrapper. 
  11.  */  
  12. protected void attachBaseContext(Context base) {  
  13.     if (mBase != null) {  
  14.         throw new IllegalStateException("Base context already set");  
  15.     }  
  16.     mBase = base;  
  17. }  
一是构造函数,一是 attachBaseContext 。
我们先来分析构造函数!Activity 继承自她,所以分析得 Activity 怎么创建的,由于 Activity 的创建过程比较复杂,而此篇重点不是他,所有我在这里直接给出结果,Activity 创建的时候调用的是无参数构造函数。所以 mBase 不是来自构造函数,那就是来自 attachBaseContext 了,下面我们来分析 Activity 在哪里调用了 attachBaseContext() 方法:
查阅 Activity 源码可以找到一处调用
[java] view plain copy
  1. final void attach(Context context, ActivityThread aThread,  
  2.         Instrumentation instr, IBinder token, int ident,  
  3.         Application application, Intent intent, ActivityInfo info,  
  4.         CharSequence title, Activity parent, String id,  
  5.         NonConfigurationInstances lastNonConfigurationInstances,  
  6.         Configuration config) {  
  7.     attachBaseContext(context);  
就是 Activity.attach 方法,此方法在 framework 创建 Activity 的时候调用的,要知道这个 context 参数是什么,我们得从 framework 代码去看,
代码:android.app.ActivityThread 
[java] view plain copy
  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.       
  3.     Activity activity = null;  
  4.     try {  
  5.         java.lang.ClassLoader cl = r.packageInfo.getClassLoader();  
  6.         activity = mInstrumentation.newActivity(  
  7.                 cl, component.getClassName(), r.intent);             
  8.     } catch (Exception e) {  
  9.     }  
  10.   
  11.     try {  
  12.         if (activity != null) {  
  13.             ContextImpl appContext = new ContextImpl();  
  14.             appContext.init(r.packageInfo, r.token, this);  
  15.             appContext.setOuterContext(activity);  
  16.   
  17.             CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());  
  18.             Configuration config = new Configuration(mCompatConfiguration);  
  19.            
  20.             activity.attach(appContext, this, getInstrumentation(), r.token,  
  21.                     r.ident, app, r.intent, r.activityInfo, title, r.parent,  
  22.                     r.embeddedID, r.lastNonConfigurationInstances, config);  
看到了,context 就是此处的 appContext 他是 ContextImpl 对象,好了,现在我们知道 ContextImpl 才是真正的实现者了。
所以 getString() 的真正调用是 ContextImpl.getResource.getString() ,getString() 的真正实现在 Resource (android.content.res.Resources) 。

有哪几种 Context?
  1. Activity :刚刚我们已经分析
  2. Service :也是继承自 ContextWrapper 跟 Activity 一样
  3. BroadcastReceiver : onReceiver(Context context )
  4. Application:
记住所有 Context 真正实现都是 ContextImpl 
Activty、Service 的 Context 都是每次创建的,而不是全局唯一,所以不要将 Activity 、Service 当做全局 Context 引用,这样会导致 Activity 无法销毁,一直被引用者。

那么什么样的 Context 才能做全局引用呢?
答案是:Application ,如果你没有自定义的 Application 怎么获取这个 Context 呢,你会发现 Context 有一个 getApplicationContext() 方法,他在 ContextImpl 的实现如下:

android.app.ContextImpl
[java] view plain copy
  1. @Override  
  2. public Context getApplicationContext() {  
  3.     return (mPackageInfo != null) ?  
  4.             mPackageInfo.getApplication() : mMainThread.getApplication();  
  5. }  

android.app.LoadedApk
[java] view plain copy
  1. Application getApplication() {  
  2.     return mApplication;  
  3. }  

这个mApplication 对象就是程序的 Application 。所以你可以把他强转成你自定义的 Application 

BroadcastReceiver 的 Context
[java] view plain copy
  1. Application app = packageInfo.makeApplication(false, mInstrumentation);  
  2.   
  3. if (localLOGV) Slog.v(  
  4.     TAG, "Performing receive of " + data.intent  
  5.     + ": app=" + app  
  6.     + ", appName=" + app.getPackageName()  
  7.     + ", pkg=" + packageInfo.getPackageName()  
  8.     + ", comp=" + data.intent.getComponent().toShortString()  
  9.     + ", dir=" + packageInfo.getAppDir());  
  10.   
  11. ContextImpl context = (ContextImpl)app.getBaseContext();  
  12. sCurrentBroadcastIntent.set(data.intent);  
  13. receiver.setPendingResult(data);  
  14. receiver.onReceive(context.getReceiverRestrictedContext(),  
  15.         data.intent);  

从代码得知,他是 Application 的 ContextImpl 对象,所以他是全局的

相关文章推荐

深入理解Android中的Context

转发来源:http://www.jianshu.com/p/94e0f9ab3f1d Context 都没弄明白,还怎么做 Android 开发?Activity mActivity =new...

android初级学习之深入理解Context

Context看起来很熟悉,基本每次进行android开发时都会用到,但是,我们又是否真的理解呢?例如,一个简单的问题,一个应用程序中到底有几个Context对象?一个,还是两个,还是多个?好吧,我们...

深入理解 Context

转载自:http://blog.csdn.net/z1074971432/article/details/12561369 什么是Context? 想必大家都不陌生,在 Android 开发中离不...

深入理解Tomcat系列之五:Context容器和Wrapper容器

前言Context容器是一个Web项目的代表,主要管理Servlet实例,在Tomcat中Servlet实例是以Wrapper出现的,现在问题是如何才能通过Context容器找到具体的Servlet呢...

android中深入理解 Context

什么是Context?想必大家都不陌生,在 Android 开发中离不开 Context 调用各种跟系统有关的 API 都必须用到 Context 。我们可以将她理解为上下文环境,大概就是里面存储一堆...

android context理解

  • 2011-12-19 22:28
  • 92KB
  • 下载

Android关于Context的简单理解

我相信大家在android开发的过程中都遇到过这样的问题,特别是初级的android程序员,今天我们就来简单的理解一下Context到底是什么呢,上下文环境是什么

Android中的Context理解

1、sdk当中关于Context的介绍 Interface to global information about an application environment. This is an abs...

Android源码分析-全面理解Context

前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答...

Android中的Context理解

一个Context意味着一个场景
  • leif_
  • leif_
  • 2016-09-05 20:14
  • 270
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)