Context
Context的继承结构中,直系子类有两个,分别是ContextImpl和ContextWrapper,而Application、Service和ContextThemeWrapper则是继承自ContextWrapper,其中Activity则是继承于ContextThemeWrapper。看到ContextThemeWrapper中的Theme应该也能快速联想到Activity的区别,在Application、Service和Activity中,只有Activity能够设置主题,也就是我们在AndroidManifest.xml中设置的相关主题属性。
Different of Context Between Application and Activity
如果是在Activity中,可以直接使用Activity.this来指代Context,当然我们也可以通过getApplicationContext()来传入Context。不过这两个Context是不同的对象,一个是Activity中的实例,一个是Application的实例。由于Application的生命周期贯穿整个应用,而Activity的生命周期可能在某个阶段开始,某个阶段结束。所以他们所持有的Context的“长度”是不同的。Application的Context会存活于整个应用生命周期,而Activity的Context会随着Activity销毁而销毁。
因此这里会有一个内存泄漏的问题,如果引用Activity的Conetxt对象的生命周期超过了当前Activity的生命周期,系统回收Activity时发现还有Context强引用则不销毁这个Activity,久会导致内存泄漏。所以一个全局静态变量在引用context时一定要使用Application的Context。
Usage Scenarios
面试中常常会被问到Application能够start an Activtiy吗?答案是不行的。这就来源于Application和Activty 各自Context的使用范围限制。其中Show a Dialog、Start an Activity和Layout Inflation这些和UI相关的都只能由Activity中的Context来处理,Application Context和Service Context都无法做相应处理。
图片来源于:Context在各个组件中使用场景
Number of Contexts
一个应用中Context的数量则取决于Activity的数量+Service的数量+一个Application