对于LayoutInflater的定义,我们来看一下官方文档,
Instantiates a layout XML file into its corresponding android.view.View objects.
意思是,将一个XML文件实例化为对应的View对象。
在实际开发中,我们避免不了需要使用到LayoutInflater类中的inflate()方法。对于LayoutInflater对象的获取,有三种方式。
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);// 第一种方式
LayoutInflater inflater = LayoutInflater.from(context);// 第二种方式
LayoutInflater inflater = activity.getLayoutInflater();// 第三种方式
那么这三种方式有什么区别呢?
(1).第一种方式
getSystemService()是Android很重要的一个API,它是Context类的一个方法,根据传入的name来取得对应的Object,然后转换成相应的服务对象。Context.LAYOUT_INFLATER_SERVICE表示我们取得的是实例化layout的服务对象。
(2).第二种方式
我们来看一下它的内部实现。
/**
* 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;
}
from()是LayoutInflater中的一个静态方法,返回LayoutInflater对象。我们可以看到,方法内部其实使用的是context.getSystemService(),也就是上述第一种方式。
(3).第三种方式
getLayoutInflater()是Activity类的一个方法,也就是说只有通过Activity类的引用才能调用,相比于第一种和第二种方式,此种方式存在一定的使用局限。我们来看一下它的内部实现。
Activity类的关键代码
package android.app;
public class Activity extends ContextThemeWrapper implements ... {
......
private Window mWindow;
......
@NonNull
public LayoutInflater getLayoutInflater() {
return getWindow().getLayoutInflater();
}
public Window getWindow() {
return mWindow;
}
final void attach(...) {
......
mWindow = new PhoneWindow(this);
......
}
......
......
}
从源码可以看到,当我们调用getLayoutInflater()方法时,方法内部先调用了getWindow()方法,而getWindow()返回的是Activity类的mWindow成员变量,mWindow是Window类的引用。当Activity被创建时,会调用attach()方法,在attach()方法里面完成mWindow成员变量赋值,mWindow实际上是PhoneWindow类的对象。Window是一个抽象类,其内部的getLayoutInflater()方法是abstract的,PhoneWindow类继承自Window类,实现了getLayoutInflater()方法,即我们最终调用的是PhoneWindow类的getLayoutInflater()方法。
Window类的关键代码
package android.view;
public abstract class Window {
......
@NonNull
public abstract LayoutInflater getLayoutInflater();
......
}
PhoneWindow类的源码SDK并未给我们提供,从Android源码中我们可以找到PhoneWindow类的实现,路径\platform_frameworks_base-master\core\java\com\android\internal\policy\PhoneWindow.java。
PhoneWindow类的关键代码
package com.android.internal.policy;
public class PhoneWindow extends Window implements MenuBuilder.Callback {
......
private LayoutInflater mLayoutInflater;
......
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public LayoutInflater getLayoutInflater() {
return mLayoutInflater;
}
......
}
到这里,真相大白了。PhoneWindow类的getLayoutInflater()方法,内部使用的其实是LayoutInflater.from(context),即上述第二种方式。
**结论:
获取LayoutInflater对象,最终都是通过调用Context类的getSystemService()方法来实现的。**