Context.getSystemService 获取 Manager 的底层实现

在分析无障碍服务接受事件响应时发现,ViewRootImpl 通过 Context.getSystemService(int) 方法获取了 AccessibilityManager,然后通过它向 AccessibilityManagerService 进行 Binder 调用,进而通知无障碍服务事件的,那么Context.getSystemService(String) 是如何获取 AccessibilityManager 的呢?这个获取流程是不是同 Binder 获取的呢?

frameworks/base/core/java/android/view/accessibility/AccessibilityManager.java 为例,介绍 XXXManager 的获取流程。通过 Context.getSystemService(String) ,获取到 AccessibilityManager 对象作为系统服务的对象。

系统行为可以通过 Context.getSystemService(ACCESSIBILITY_SERVICE) 获取 AccessibilityManager 对象进行调用,系统的服务统一在 frameworks/base/core/java/android/app/SystemServiceRegistry.java 中进行注册:

    static {
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() 
{
            @Override
            public AccessibilityManager createService(ContextImpl ctx) {
                return AccessibilityManager.getInstance(ctx);
            }});
        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() 
{
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
        // ...
    }

Manager 的创建是在 Context.getSystemService(String) 方法中开始的,它的实际实现是在 ContextImpl 中:

    @Override
    public Object getSystemService(String name) {
        // ...
        return SystemServiceRegistry.getSystemService(this, name);
    }

最终调用到了 SystemServiceRegistry 中:

    // in SystemServiceRegistry
    public static Object getSystemService(ContextImpl ctx, String name) {
        if (name == null) {
            return null;
        }
        final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        if (fetcher == null) {
            return null;
        }

        final Object ret = fetcher.getService(ctx);
        if (sEnableServiceNotFoundWtf && ret == null) {
            switch (name) {
                case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
                case Context.APP_PREDICTION_SERVICE:
                case Context.INCREMENTAL_SERVICE:
                case Context.ETHERNET_SERVICE:
                    return null;
            }
            return null;
        }
        return ret;
    }

在这个方法中,通过 ServiceFetcher 的 getService(ContextImpl) 方法返回了最终获取到的对象,而这个 ServiceFetcher 来自于 SYSTEM_SERVICE_FETCHERS ,它是一个 Map:

private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();

往这个 Map 中存数据的调用在 registerService 中,也就是 SystemServiceRegistry 静态代码块中,注册的逻辑。

        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() 
{
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});

这里在注册时,传入了一个 CachedServiceFetcher 对象,最终调用到的就是它的 getService :

public final T getService(ContextImpl ctx) {
    final Object[] cache = ctx.mServiceCache;
    final int[] gates = ctx.mServiceInitializationStateArray;
    boolean interrupted = false;
    T ret = null;
    for (;;) {
        boolean doInitialize = false;
        synchronized (cache) {
            T service = (T) cache[mCacheIndex];
            if (service != null) {
                ret = service;
                break// exit the for (;;)
            }
            if (gates[mCacheIndex] == ContextImpl.STATE_READY || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
                gates[mCacheIndex] = ContextImpl.STATE_UNINITIALIZED;
            }
            if (gates[mCacheIndex] == ContextImpl.STATE_UNINITIALIZED) {
                doInitialize = true;
                gates[mCacheIndex] = ContextImpl.STATE_INITIALIZING;
            }
        }

        if (doInitialize) { // Only the first thread gets here.
            
            T service = null;
            @ServiceInitializationState int newState = ContextImpl.STATE_NOT_FOUND;
            try {
      // This thread is the first one to get here. 
                service = createService(ctx); // 【*】
                newState = ContextImpl.STATE_READY;

            } catch (ServiceNotFoundException e) {
                onServiceNotFound(e);

            } finally {
                synchronized (cache) {
                    cache[mCacheIndex] = service;
                    gates[mCacheIndex] = newState;
                    cache.notifyAll();
                }
            }
            ret = service;
            break// exit the for (;;)
        }
        // and go back to the top and retry. 其他线程将会等待第一个线程调用 notifyAll(), 返回 top 并且重试
        synchronized (cache) {
            while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
                try {
                    interrupted |= Thread.interrupted();
                    cache.wait();
                } catch (InterruptedException e) {
                    Slog.w(TAG, "getService() interrupted");
                    interrupted = true;
                }
            }
        }
    }
    if (interrupted) {
        Thread.currentThread().interrupt();
    }
    return ret;
}

这里执行了三个步骤:

  • 缓存中直接获取对象,尝试获取若显示未初始化,则进入初始化服务阶段
  • 调用 createService(contextImpl) 创建服务
  • 其他线程等待当前线程创建完成更新缓存

从这几个步骤可以发现,创建逻辑调用到了 createService(contextImpl) 方法,而这个方法,在 registerService 时,不同的服务有不同的实现,例如 AccessbilityManager 和 ActivityManager 是直接 new 了一个对象。有的则是通过 Binder 机制,获取了一个 IBinder,并将其封装为指定类型的服务:

    // 直接 new
        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() 
{
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
    // binder 获取后封装
        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);
            }});
    // ... 

至此, XXXManager 的获取流程就结束了。从代码结构上看,这是一个标准的策略模式。


原文始发于微信公众号(八千里路山与海):Context.getSystemService 获取 Manager 的底层实现

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/60192.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!