get****Context各个方法分析
1 getApplicationContext分析
该方法为contextImpl类的方法,返回一个ApplicationContext。方法代码为:
public Context getApplicationContext() { return (mPackageInfo != null) ? mPackageInfo.getApplication() : mMainThread.getApplication(); } |
1.1 mPackageInfo.getApplication()分析
如果mPackeageInfo对象(LoadedApk类,全局唯一)不为空,就调用mPackageInfo的getApplication方法。该方法返回mPackageInfo对象中的mApplication对象。LoadedApk类中的mApplication只在一个地方被赋值:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; //如果mApplication不为空,就直接返回该值,说明android只允许一个APK含有一个application对象 } //否则就创建一个Application对象 Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { //如果app类名为空,或者指定要求使用默认app类名,就使用这个类名 appClass = "android.app.Application"; } //开始新建一个application对象 try { java.lang.ClassLoader cl = getClassLoader(); //首先创建一个ContextImpl对象 ContextImpl appContext = new ContextImpl(); appContext.init(this, null, mActivityThread); //初始化 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { …… } //将此app加入到mAllApplications链表中 mActivityThread.mAllApplications.add(app); mApplication = app; //这里完成给mApplication赋值 ……. return app; } |
通过上面的分析,可以知道mPackageInfo.getApplication()方法返回当前APK的唯一的Application对象。
1.2 mMainThread.getApplication()分析
如果mPackeageInfo对象为空,就调用此方法。关于mPackeageInfo相关知识,目前还没分析透,待分析完全之后补充。
mMainThread为ActivityThread类,所以我们需要去ActivityThread.java中找寻答案。该类的getApplication方法返回mInitialApplication对象,此对象也是Application类。同样的分析方法,我们去探寻该对象是如何被赋值的。
在ActivityThread类中共有两个地方对其进行了赋值,第一处的代码如下:
private void handleBindApplication(AppBindData data) { …… try { // If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; …… } |
显然mInitialApplication对象是通过makeApplication方法创建的,所以这里的mInitialApplication与mPackageInfo.getApplication()方法返回的Application是同一个对象。同时需要说明一下handleBindApplication函数。该函数会在应用程序第一次启动时调用。具体点说就是:在启动应用程序时ActivityManagerService类中的onTranct方法会调用ActivityThread.bindApplication方法,此方法有两种参数(一为applicationInfo,二为其他相关函数);在bindApplication中会根据这两种参数构建一个AppBindData对象data,然后以此对象为参数调用sendMessage(int what = H.BIND_APPLICATION, Object m = data;过后系统就会在消息处理函数ActivityThread.handleMessage(int what)中调用handleBindApplication(AppBindData data)创建ApplicationContext对象。
另一处的代码如下:
private void attach(boolean system) { if (!system) { …… } else {//如果是系统进程,那么就调用以下代码 // Don't set // we can't android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = ContextImpl context = new ContextImpl(); context.init(getSystemContext().mPackageInfo, null, this); Application app = mAllApplications.add(app); mInitialApplication = app; app.onCreate(); } catch throw new "Unable to instantiate Application():" + e.toString(), e); } } } |
对比此处红色部分的代码,和上面makeApplication方法的代码,可以发现两者其实都是创建一个Application对象。不过attach方法只在FrameWork进程(system_server)启动时调用,应用程序运行时并不会调用此方法。所以这里可以忽略。
总之,对应用程序而言getApplicationContext方法返回的都是应用程序的唯一ApplicationContext。
2 getBaseContext分析
此方法在ContextWrapper类中定义。代码如下:
public Context getBaseContext() { return mBase; } |
这里的mBase就是一个Context对象,getBaseContext()
返回由ContextWrapper类的构造函数指定或attachBaseContext ()设置的Context,SDK文档很少,不推荐使用。
3 Activity.this分析
Activity.this返回当前activity的context,这个context属于当前的activity,会随着activity的摧毁而摧毁。
4 getContext
该方法比较特殊,特殊的原因不是它复杂,而是它的不确定性。因为并不是每一个类都有该方法,也不是每一个类中该方法的作用均相同。如在android.view类,它就返回当前view所运行的context,一般情况下是当前的activity的context。而在contentProvider类中,该方法返回的是ApplicationContext(在ActivityThread.installProvider中可以知道)。所以该方法的返回值要根据具体情况具体分析。
总结
了解了所有的获取context相关的函数过后,我们就可以很容易的理解下面的问题了:
this: 当前activity的context,生命周期为当前activity的生命周期。
This.getApplicationContext:返回整个应用程序的application
context,生命周期为整个应用程序。
get****Context各个方法分析的更多相关文章
- 【转】第7篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:全自动注册与反射方法分析
作者: 牛A与牛C之间 时间: 2013-12-12 分类: 技术文章 | 2条评论 | 编辑文章 主页 » 技术文章 » 第7篇:Xilium CefGlue 关于 CLR Object 与 JS ...
- 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件
博客地址 : http://blog.csdn.net/shulianghan/article/details/41520569 代码下载 : -- GitHub : https://github.c ...
- c# AOP编程:Context与方法拦截
之前做AgentBooking时候,遇到两个问题比较棘手,一个是异常的传递与捕获:如何可以合理地在层层代码调用中统一传递并统一捕获异常.因为如果有一个做法,可以地方统一处理异常,可以使代码减少很多tr ...
- SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析
目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析
前篇博客LZ已经分析了ReentrantLock的lock()实现过程,我们了解到lock实现机制有公平锁和非公平锁,两者的主要区别在于公平锁要按照CLH队列等待获取锁,而非公平锁无视CLH队列直接获 ...
- php模拟登陆的两种实现方法分析
php模拟登陆的实现方法分析 本文实例分析了php模拟登陆的实现方法.分享给大家供大家参考.具体分析如下: php模拟登陆的实现方法,这里分别列举两种方法实现模拟登陆人人网.具体实例代码如下: 1)使 ...
- Servlet生命周期中的service方法分析
问题ServletLifeCycle中的service方法内,有super.service(request, response); 会执行this.doGet(HttpServletRequest r ...
- KCF目标跟踪方法分析与总结
KCF目标跟踪方法分析与总结 correlation filter Kernelized correlation filter tracking 读"J. F. Henriques, R. ...
- Android 缓存目录 Context.getExternalFilesDir()和Context.getExternalCacheDir()方法
一.基础知识 应用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的.大部分应用是直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中.这样当该应用被卸载 ...
随机推荐
- 第十一篇、UITableView headerview下拉放大
核心代码: -(void)createTableViewHeaderView{ _tableViewHeaderView = [[UIView alloc] initWithFrame:(CGRect ...
- 已解决: idea创建并部署SpringMVC项目时 报错 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
用IDEA创建并运行SpringMVC项目时,最初发现没有Servlet包,这个问题已在上篇解决,然而当我们尝试去运行此时的SpringMVC项目时,发现仍然有错误.ClassNotFoundExce ...
- 2- vue django restful framework 打造生鲜超市 -环境搭建
使用Python3.6与Django2.0.2(Django-rest-framework)以及前端vue开发的前后端分离的商城网站 项目支持支付宝支付(暂不支持微信支付),支持手机短信验证码注册, ...
- vue.js devtools安装
在调试的时候chrome会提示安装vue devtools,我以为是要在chrome的程序商店直接安装,但是国内对谷歌的和谐,无法访问谷歌商店内容 官方有源代码,可以下载下来自行编译安装 官方地址:h ...
- java中常用的swing组件 (2013-10-27-163 写的日志迁移
五种布局: 流式布局(FlowLayout)边界布局(borderLayout)网格布局(GridLayout) 盒子布局(BoxLaYout) 空布局(null) 常用的几种 卡片布局(C ...
- Python入门基础--变量与基本数据类型
变量 什么是变量 变量就是变化的量,变就是变化,量用于衡量描述对象的状态 为什么要有变量 程序执行的本质就是一系列状态的变化,变是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程序 ...
- 安装 ubuntu 后,使用 sed 更换国内源
cd /etc/aptsed -i "s/archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list也可以使用 1 ...
- greenplum-时间处理
工作中遇到,需要改变两周以前的数据状态,于是查了下资料,原来数据库直接就可以处理,所以分享给大家! 在PostgreSQL中可以直接对时间进行加减运算:. SELECT now()::timestam ...
- Android 停止调试程序
现在我知道怎么停掉debug的Android程序了,很简单,进入ddms界面,对着你的进程,kill.
- 【IPv6】ISATAP隧道技术详解
一.基本概念 ISATAP(Intra-SiteAutomatic Tunnel Addressing Protocol) ISATAP是一种非常容易部署和使用的IPv6过渡机制.在 ...