自动化零件商城(www.rssme.com)专业PLC,变频器,直线模组,触摸屏,控制器,传感器等自动化商品网上购物商城,为广大中小工业企业提供优质、低价格和种类齐全的自动化零件。
文章目录

前言

接上文《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

相关文章

自动化零件商城(www.rssme.com)专业PLC,变频器,直线模组,触摸屏,控制器,传感器等自动化商品网上购物商城,为广大中小工业企业提供优质、低价格和种类齐全的自动化零件。

暂无评论

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

none
暂无评论...