/**
* 每天一个知识点day14 TODO Context
* Context可以理解为上下文,背景,环境。Context本身是一个抽象类,它有两个实现类
* ContextImpl和ContextWrapper,ContextWrapper构造函数中必须包含一个真正的Context引用,
* 同时ContextWrapper中提供了attachBaseContext()
* 用于给ContextWrapper对象中指定真正的Context对象,
* 调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。
* ContextThemeWrapper是ContextWrapper的子类,内部包含主题相关的接口,这里的主题指的是
* AndroidManifest.xml通过android:theme为Application元素或者Activity元素指定的主题,
* 只有Activity需要主题,Service不需要,所以Service继承于ContextWrapper。
* ContextWrapper是Context的包装类,Activity、Service、Application虽然都继承自ContextWrapper
* 但他们初始化的过程都会创建ContextImpl对象,由ContextImpl实现Context中的方法。
*
* 一个应用程序Context的数量 = Activity的数量 + Service的数量 + 1
* Broadcast Receiver,Content Provider并不是Context的子类,
* 他们所持有的Context都是其他地方传过去的,所以并不计入Context总数。
*
* 如何获取Context?
* 1.View.getContext(),返回当前View对象的Context对象,通常是当前正在展示的Activity对象。
* 2.Activity.getApplicationContext(),获取当前Activity所在的(应用)进程的Context对象,
* 通常我们使用Context对象时,要优先考虑这个全局的进程Context。
* 3.ContextWrapper.getBaseContext():用来获取一个ContextWrapper进行装饰之前的Context,
* 可以使用这个方法,这个方法在实际开发中使用并不多,也不建议使用。
* 4.Activity.this 返回当前的Activity实例,如果是UI控件需要使用Activity作为Context对象,
* 但是默认的Toast实际上使用ApplicationContext也可以。
*
* getApplication()和getApplicationContext()的区别?
* Application本身就是一个Context,
* 所以这里获取getApplicationContext()得到的结果就是Application本身的实例。
* 实际上这两个方法在作用域上有比较大的区别。getApplication()方法的语义性非常强,
* 一看就知道是用来获取Application实例的,但是这个方法只有在Activity和Service中才能调用的到。
* 那么也许在绝大多数情况下我们都是在Activity或者Service中使用Application的,
* 但是如果在一些其它的场景,比如BroadcastReceiver中也想获得Application的实例,
* 这时就可以借助getApplicationContext()方法了。
*
* 错误的使用Context可能引起内存泄漏。
* 正确使用Context
* 一般Context造成的内存泄漏,几乎都是当Context销毁的时候,
* 却因为被引用导致销毁失败,而Application的Context对象可以理解为随着进程存在的,
* 所以我们总结出使用Context的正确姿势:
* 1.当Application的Context能搞定的情况下,并且生命周期长的对象,优先使用Application的Context。
* 2.不要让生命周期长于Activity的对象持有到Activity的引用。
* 3.尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用,
* 如果使用静态内部类,将外部实例引用作为弱引用持有。
*/
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Application application = getApplication();
Context context = getApplicationContext();
Log.d("dww", "getApplication()" + application);
Log.d("dww", "getApplicationContext()" + context);
//打印getApplication()android.app.Application@84251f7
//打印getApplicationContext()android.app.Application@84251f7
}
网友评论