答案是不一定。
如果这个 View
是我们构造出来的,那它的 getContext()
返回的是我们构造它的时候传入的 Context
类型。
如果是 XML
里面的 View
呢,会怎样?
先看结论:直接继承 Activity
构造出来的 View
, View.getContext()
返回的是当前 Activity
。但是:当 View
的 Activity
是继承自 AppCompatActivity
,并且在 Android 5.0
以下版本的手机上时, View.getContext()
得到的并非是 Activity
,而是 TintContextWrapper
。
Activity.setContentView()
setContentView()
时,其加载过程为:
Activity.setContentView
-> PhoneWindow.setContentView
-> LayoutInflater.inflate
-> LayoutInflater.createViewFromTag
-> LayoutInflater.onCreateView
-> LayoutInflater.createView
最终在 createView()
方法中来实例化 XML
文件中的 View
,可以看到传参的 context
是 LayoutInflater
的 context
,而 LayoutInflater
是在 PhoneWindow
中创建的,其 context
是 PhoneWindow
的 context
, 而 PhoneWindow
的初始化是在 Activity
的 attach()
方法中,所以 PhoneWindow
的 context
就是 Activity
本身。
AppCompatActivity.setContentView()
我们重点来看看 AppCompatActivity
的 setContentView()
是怎么实现的。
public void setContentView(@LayoutRes int layoutResID) {
this.getDelegate().setContentView(layoutResID);
}
@NonNull
public AppCompatDelegate getDelegate() {
if (this.mDelegate == null) {
this.mDelegate = AppCompatDelegate.create(this, this);
}
return this.mDelegate;
}
这个 mDelegate
实际上是一个代理类,由 AppCompatDelegate
根据不同的 SDK 版本生成不同的实际执行类,就是代理类的兼容模式:
/**
* Create a {@link android.support.v7.app.AppCompatDelegate} to use with {@code activity}.
*
* @param callback An optio