LayoutInflater.from(context)
是我们非常常用的方法,在Activity
也可以调用getLayoutInflater()
获取,可能这其中也有一些需要注意的地方。
先运行下面一段代码,猜猜运行结果,这三个方法运行后得到的是同一个对象吗?public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "onCreate -->LayoutInflater.from(this): "+LayoutInflater.from(this));
Log.e(TAG, "onCreate -->getLayoutInflater(): "+getLayoutInflater());
Log.e(TAG, "onCreate -->LayoutInflater.from(getApplicationContext()): "+LayoutInflater.from(getApplicationContext()));
}
}
下面看看结果:12-25 16:20:24.716 26432-26432/? E/MainActivity: onCreate -->LayoutInflater.from(this): com.android.internal.policy.PhoneLayoutInflater@f8ec208
12-25 16:20:24.716 26432-26432/? E/MainActivity: onCreate -->getLayoutInflater(): com.android.internal.policy.PhoneLayoutInflater@f8ec208
12-25 16:20:24.716 26432-26432/? E/MainActivity: onCreate -->LayoutInflater.from(getApplicationContext()): com.android.internal.policy.PhoneLayoutInflater@9173da1
也就是LayoutInflater.from(Activity.this)
和Activity.getLayoutInflater()
得到的是同一个对象,
而LayoutInflater.from(getApplicationContext())
并不相同,这就要注意在使用时有什么区别了。
我们先看看LayoutInflater.from(context)
是怎么处理的
LayoutInflater.java/**
* Obtains the LayoutInflater from the given context.
*/
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
其中context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
又有多种实现,先来看看Activity
的:
Activity.java
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
}
继续追踪super.getSystemService(name);
ContextThemeWrapper.java
public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
看到了我们熟悉的LAYOUT_INFLATER_SERVICE
,并且根据代码可以看到每个Activity
都会有一个自己独立的mInflater
属性。
我们再来跟踪一下ApplicationContext
是怎么处理的
可以在SystemServiceRegistry.java
中看到服务的注册方式
SystemServiceRegistry.java//...
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
说白了是在整个app生命周期中会有一个原始的LayoutInflater
对象,但是通过Activity创建的LayoutInflater对象中会持有Activity
对象,这个context在创建View
的构造方法中传入,所以,在使用LayoutInflater.from(context).inflate()
创建出是如果要使用view.getContext()
与 LayoutInflater.from(context)
的context相同。