文章目录
接上文《》,知道最终都调用到
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; }
也就是把LAYOUT_INFLATER_SERVICE的关键key传入context.getSystemService()获取LayoutInflater的服务。
之前没有跟,今天继续跟一下。
正文
我们看getSystemService()这个方法
Context.java
getSystemService()
@SuppressWarnings("unchecked") public final @Nullable <T> T getSystemService(@NonNull Class<T> serviceClass) { // String serviceName = getSystemServiceName(serviceClass); return serviceName != null ? (T)getSystemService(serviceName) : null; }
getSystemService()
此方法抽象的
public abstract @Nullable String getSystemServiceName(@NonNull Class<?> serviceClass);
Context的实现类为ContextImpl
ContextImpl.java
getSystemServiceName()
@Override public String getSystemServiceName(Class<?> serviceClass) { //调用的SystemServiceRegistry的方法 return SystemServiceRegistry.getSystemServiceName(serviceClass); }
SystemServiceRegistry.java
getSystemServiceName()
public static String getSystemServiceName(Class<?> serviceClass) { if (serviceClass == null) { return null; } //SYSTEM_SERVICE_NAMES是一个map列表,服务注册时会保存到这里 final String serviceName = SYSTEM_SERVICE_NAMES.get(serviceClass); if (sEnableServiceNotFoundWtf && serviceName == null) { // This should be a caller bug. Slog.wtf(TAG, "Unknown manager requested: " + serviceClass.getCanonicalName()); } return serviceName; }
重点关注一下SYSTEM_SERVICE_NAMES这个map列表。
private static final Map<Class<?>, String> SYSTEM_SERVICE_NAMES = new ArrayMap<Class<?>, String>();
当服务注册时存在到上面列表中
registerService()
private static <T> void registerService(@NonNull String serviceName, @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName()); }
回到上面,我们关注的是LAYOUT_INFLATER_SERVICE,注册是也是在SystemServiceRegistry.java。
通过搜素,发现很多服务的注册在static静态代码块中。
static{}
static { //CHECKSTYLE:OFF IndentationCheck registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() { @Override public AccessibilityManager createService(ContextImpl ctx) { return AccessibilityManager.getInstance(ctx); }}); registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class, new CachedServiceFetcher<CaptioningManager>() { @Override public CaptioningManager createService(ContextImpl ctx) { return new CaptioningManager(ctx); }}); registerService(Context.ACCOUNT_SERVICE, AccountManager.class, new CachedServiceFetcher<AccountManager>() { @Override public AccountManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(Context.ACCOUNT_SERVICE); IAccountManager service = IAccountManager.Stub.asInterface(b); return new AccountManager(ctx, service); }}); //略 //注册LAYOUT_INFLATER_SERVICE服务 registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, new CachedServiceFetcher<LayoutInflater>() { @Override public LayoutInflater createService(ContextImpl ctx) { //创建的PhoneLayoutInflater() return new PhoneLayoutInflater(ctx.getOuterContext()); }}); //略 }
PhoneLayoutInflater.java
PhoneLayoutInflater继承LayoutInflater
public class PhoneLayoutInflater extends LayoutInflater { private static final String[] sClassPrefixList = { "android.widget.", "android.webkit.", "android.app." }; public PhoneLayoutInflater(Context context) { super(context); } protected PhoneLayoutInflater(LayoutInflater original, Context newContext) { super(original, newContext); } @Override protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException { for (String prefix : sClassPrefixList) { try { View view = createView(name, prefix, attrs); if (view != null) { return view; } } catch (ClassNotFoundException e) { } } return super.onCreateView(name, attrs); } public LayoutInflater cloneInContext(Context newContext) { return new PhoneLayoutInflater(this, newContext); } }
上面调用的是
protected PhoneLayoutInflater(LayoutInflater original, Context newContext) { super(original, newContext); }
这里又调用super,也就是父类LayoutInflater的构造函数。
LayoutInflater.java
protected LayoutInflater(LayoutInflater original, Context newContext) { StrictMode.assertConfigurationContext(newContext, "LayoutInflater"); mContext = newContext; mFactory = original.mFactory; mFactory2 = original.mFactory2; mPrivateFactory = original.mPrivateFactory; setFilter(original.mFilter); initPrecompiledViews(); }
参考文章
《》
《