> View.getContext()
Context context = imageView.getContext();
if (context instanceof Activity) {
Activity activity = (Activity)context;
// ...
}
在 5.0 以下,这个 imageView.getContext() 获取到的 context 类型不是我一开始以为的 Activity 类型,而是 TintContextWrapper 类型。 控件所在的 Activity 是继承自 AppCompatActivity ,这个 context 类型的变化一定是和 v7 包里的 AppCompatActivity 有关系。
view的context就是LayoutInflater的mContext:这个LayoutInflater的context是PhoneWindow传进去的:PhoneWindow的context就是Activity的this 。
所有Appcompat的Activity,创建View的时候,都会对基本View做一个风格的包装,也就是说ImageView会变成AppcompatImageView。 那么实际上,imageView.context 是AppcompatImageView的getContext().发现即使context传进来是个activity,也回被包装成TintContextWrapper。那么为什么5.0以上系统,获得的还是一个Activity呢?
private static AppCompatDelegate create(Context context, Window window,
AppCompatCallback callback) {
final int sdk = Build.VERSION.SDK_INT;
if (BuildCompat.isAtLeastN()) {
return new AppCompatDelegateImplN(context, window, callback);
} else if (sdk >= 23) {
return new AppCompatDelegateImplV23(context, window, callback);
} else if (sdk >= 14) {
return new AppCompatDelegateImplV14(context, window, callback);
} else if (sdk >= 11) {
return new AppCompatDelegateImplV11(context, window, callback);
} else {
return new AppCompatDelegateImplV9(context, window, callback);
}
}
View.getContext() 里的小秘密- https://blog.csdn.net/weixin_34380948/article/details/88029324
-- View.getContext() 如何强制转为 Activity ?
@Nullable
private Activity getActivity(@NonNull View view) {
if (null != view) {
Context context = view.getContext();
while (context instanceof ContextWrapper) {
if (context instanceof Activity) {
return (Activity) context;
}
context = ((ContextWrapper) context).getBaseContext();
}
}
return null;
}
> Activity等的Context
Context的两个子类分工明确,其中ContextImpl是Context的具体实现类,ContextWrapper是Context的包装类。Activity,Application,Service虽都继承自ContextWrapper(Activity继承自ContextWrapper的子类ContextThemeWrapper),但它们初始化的过程中都会创建ContextImpl对象,由ContextImpl实现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也可以。