本文参考 Android Context 是什么?进行的自我学习总结。
我们会经常用Context来获取资源,启动服务,创建View,启动Activity,绑定Service,发广播,etc。
** 带着问题:**
Context的定义?
Context源码实现?
Context分类及使用注意点?
定义:提供一个应用运行所需要的信息,资源,系统服务的一个运行环境,资源依赖。通俗说是“上下文”。
AndroidStudio里用Type Hierarchy(ctrl+h)看下类的继承派生关系:
可以清晰看到Context有二个直接子类,MockContext是用于测试的,ContextWrapper是我们要关心的。
Application与Service都继承自ContextWrapper。
Activity不是直接继承ContextWrapper,而是继承ContextThemWrapper。ContextThemWrapper扩展了主题相关的方法。
有人说Application也有主题,Application的主题最终由Activity承载。
LayoutInflater from方法也是调用系统服务来实现。
Application类是继承自ContextWrapper类。
在attach方法中,调用父类ContextWrapper中的attachBaseContext方法来对ContextWrapper的成员变量mBase赋值成ContextImpl对象。
Application的attachBaseContext()方法是挺重要的,覆盖它一些需要抢时间的全局初始化的工作。
解开了java程序由main方法启动的疑惑:每一个App应用都是由ASM通过Binder机制创建一个新的进程然后调用ActivityThread类中的main方法开始的。整个App应用的入口在ActivityThread.main方法里面!
getApplication和getApplicationContext得到的对象本质没有区别,仅仅是返回类型和实现方法的地方不同,getApplication是Activity才有的。
Dialog与startActivity启动非FLAG_ACTIVITY_NEW_TASK标记的Activity Context必须是Activity类型。
LayoutInflater.from(Context context)由于只是静态资源加载,Context无限制。
view的创建与getResource,资源加载理论是可以使用任意的Context,但尽量用Activity类型.getResource().getDrawable(R.drawable....)在小米4.4.2系统用application类型的会造成了崩溃,改用Activity就没事了
特别注意在!!!异步延时!!!使用Activity创建Dialog显示,极易造成Crash。Activity是否finish。
if (mActivity.isFinishing()) {
Log.e(TAG, "onPostExecute: mActivity.isFinishing()"); return;
}
builder.show();
Unable to add window -- token android.os.BinderProxy@25f520a6 is not valid; is your activity running?
同步延时就类ANR了。