View.getContext()与Activity的Context

> 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也可以。

猜你喜欢

转载自blog.csdn.net/ShareUs/article/details/89498707