理解Context

什么是Context

Context: 字面理解为上下文,语境。Android应用模型是基于组件的应用设计模式,组件的运行要有一个完整的Android工程环境,在这个环境下,Activity、Service等系统组件才能够正常工作,而这些组件并不能采用普通的Java对象创建方式,即比如Activity mActivity =new Activity()是不允许的,而是要有它们各自的上下文环境,也就是我们这里讨论的Context。

在程序中,可以理解为当前对象在程序中所处的一个环境,一个与系统交互的过程

ContextImpl:Context的基础实现类,为activity和其他application 组件提供了Context对象

ContextWrapper:Context的代理实现,具体实现为ContextImpl,他只是一个代理类

ContextThemeWrapper:继承ContextWrapper,修改了主题相关的API

Activity:继承ContextThemeWrapper

Service:继承ContextWrapper

Application:继承ContextWrapper

即Activity,Application,Service都是Context

而另外两大组件ContentProvider,BroadcastReceiver,以及View都持有Context的引用,可以说在Android中Context无处不在

Application,Activity,Service作为Context的区别

动作 Application Activity Service
show a Dialog no yes no
start a activity 不推荐 yes 不推荐
layout inflation 不推荐 yes 不推荐
start a service yes yes yes
start a broadcast yes yes yes
register broadcast receiver yes yes yes
load resource values yes yes yes
1:Application(Service)和Activity的startActivity是不同的。

Application的startActivity是调用的ContextImpl中StartActivity,
而Activity中重写了startActivity,最后调用的是Activity中的startActivityForResult方法

Application和Service不能启动LaunchMode为standard的Activity。这是由于非Activity类型的Context并没有所谓的任务栈,所以待启动的Activity就找不到栈了,Application和Service只能启动FLAG_ACTIVITY_NEW_TASK类的Activity,这样启动的时候就为它创建一个新的任务栈

2. Dialog的Context一般情况下只能用Activity

系统定义了三种Window

  1. 应用窗口:窗口需要对应一个Activity(具体实现可参考Window相关资料)。
  2. 系统窗口:不需要对应任何Activity,也不需要有父窗口,对于应用程序而言,理论上是无法创建系统窗口的,因为所有的应用程序都没有这个权限。
  3. 子窗口:该窗口必须有一个父窗口

因此 我们一般创建一个Window,或者启动一个Dialog(内部也是Window实现),需要用Activity的Context。

3. layout inflate的区别

Application和Service中去layout inflate也是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用

4. Application,Activity,Service的生命周期是不同的。

所以引用的时候要防止内存泄漏,一般三者都能使用的情况下,使用Application可以有效的防止内存泄漏,因为Application的生命周期是整个App持续周期

生命周期长于Activity的对象持有到Activity的引用时,可能引起内存泄漏

Activity中使用非静态内部类,由于非静态内部类会隐式持有外部类实例的引用,所以也可能造成内存泄漏,一般可以使用静态内部类,用弱引用的持有外部Activity的引用来解决

你可能感兴趣的:(理解Context)