Context.getSystemService 获取 Manager 的底层实现

1,094 阅读2分钟

在分析无障碍服务接受事件响应时发现,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 的获取流程就结束了。从代码结构上看,这是一个标准的策略模式。