前言

接上文《LayoutInflaterinflate()简单分析》,知道最终都调用到

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(); }

到此,LayoutInflater对象已经创建。

参考文章

  1. LayoutInflater之inflate()简单分析

  2. 遇见LayoutInflater&Factory

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...