mFactory = mFactory2 = new FactoryMerger(factory, factory, mFactory, mFactory2);
}
}
private static class FactoryMerger implements Factory2 {
private final Factory mF1, mF2;
private final Factory2 mF12, mF22;
FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) {
mF1 = f1;
mF2 = f2;
mF12 = f12;
mF22 = f22;
}
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = mF1.onCreateView(name, context, attrs);
if (v != null) return v;
return mF2.onCreateView(name, context, attrs);
}
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
-
View v = mF12 != null ? mF12.onCreateView(parent, name, context, attrs)
- mF1.onCreateView(name, context, attrs);
if (v != null) return v;
-
return mF22 != null ? mF22.onCreateView(parent, name, context, attrs)
- mF2.onCreateView(name, context, attrs);
}
}
然后我们再看 mPrivateFactory,看名称就知道是系统的隐藏方法。
调用时机是在 Activity.attach 中,Activity 其实是实现了 Factory2 的 onCreateView 方法,其中对 fragment 做了处理,如果是 fragment 标签,就调用 fragment 的 onCreateView,这里就不详细往下面看了,如果是非 fragment 的标签,就返回 null,走默认的创建 View 的方法。
/**
- @hide for use by framework
*/
public void setPrivateFactory(Factory2 factory) {
if (mPrivateFactory == null) {
mPrivateFactory = factory;
} else {
mPrivateFactory = new FactoryMerger(factory, factory, mPrivateFactory, mPrivateFactory);
}
}
// Activity
final void attach(…)
mWindow.getLayoutInflater().setPrivateFactory(this);
}
public View onCreateView(String name, Context context, AttributeSet attrs) {
return null;
}
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
if (!“fragment”.equals(name)) {
return onCreateView(name, context, attrs);
}
return mFragments.onCreateView(parent, name, context, attrs);
}
所以上面的 Factory 和 Factory2,是系统留给我们的 hook View 创建流程的接口。
如果都没有设置,那就走到默认的创建 View 的方法。
默认创建 View 的方法比较简单,就是反射调用 View 的构造函数,然后做一个缓存,然后创建 View。
具体代码如下
// LayoutInflate
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
boolean ignoreThemeAttr) {
// 前面的 mFactory、mFactory2、mPrivateFactory 都没有去创建 View
if (view == null) {
final Object lastContext = mConstructorArgs[0];
mConstructorArgs[0] = context;
try {
if (-1 == name.indexOf(‘.’)) {
// 如果名称里没有 “.”,也就是系统的 View,需要添加 android.view. 前缀,比如 ,最终去创建的名称是 android.view.LinearLayout
view = onCreateView(parent, name, attrs);
} else {
// 如果是自定义 View,则直接去创建
view = createView(name, null, attrs);
}
} finally {
mConstructorArgs[0] = lastContext;
}
}
// …
}
protected View onCreateView(String name, AttributeSet attrs)
throws ClassNotFoundException {
return createView(name, “android.view.”, attrs);
}
public final View createView(String name, String prefix, AttributeSet attrs)
throws ClassNotFoundException, InflateException {
Constructor<? extends View> constructor = sConstructorMap.get(name);
if (constructor != null && !verifyClassLoader(constructor)) {
constructor = null;
sConstructorMap.remove(name);
}
Class<? extends View> clazz = null;
try {
if (constructor == null) {
// 加载对应的类
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
// 反射获取构造函数
constructor = clazz.getConstructor(mConstructorSignature);
constructor.setAccessible(true);
// 做个缓存,下次直接使用,提高效率
sConstructorMap.put(name, constructor);
} else {
}
Object lastContext = mConstructorArgs[0];
if (mConstructorArgs[0] == null) {
// Fill in the context if not already within inflation.
mConstructorArgs[0] = mContext;
}
Object[] args = mConstructorArgs;
args[1] = attrs;
// 调用构造函数创建 View
final View view = constructor.newInstance(args);
if (view instance