Android中的getSystemService

getSystemService的定义

// frameworks/base/core/java/android/app/ContextImpl.java
    @Override
    public Object getSystemService(String name) {
        if (vmIncorrectContextUseEnabled()) {
            // Check incorrect Context usage.
            if (WINDOW_SERVICE.equals(name) && !isUiContext()) {
                final String errorMessage = "Tried to access visual service "
                        + SystemServiceRegistry.getSystemServiceClassName(name)
                        + " from a non-visual Context:" + getOuterContext();
                final String message = "WindowManager should be accessed from Activity or other "
                        + "visual Context. Use an Activity or a Context created with "
                        + "Context#createWindowContext(int, Bundle), which are adjusted to "
                        + "the configuration and visual bounds of an area on screen.";
                final Exception exception = new IllegalAccessException(errorMessage);
                StrictMode.onIncorrectContextUsed(message, exception);
                Log.e(TAG, errorMessage + " " + message, exception);
            }
        }
        return SystemServiceRegistry.getSystemService(this, name);
    }

然后就是调用SystemServiceRegistry中的getSystemService(ContextImpl ctx, String name)

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
    public static Object getSystemService(ContextImpl ctx, String name) {
        if (name == null) {
            return null;
        }
        // 关键点就是 ServiceFetcher 是什么
        // 或许可以理解为 Service service在本地(当前进程)中的一个副本?
        final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        if (fetcher == null) {
            if (sEnableServiceNotFoundWtf) {
                Slog.wtf(TAG, "Unknown manager requested: " + name);
            }
            return null;
        }

        final Object ret = fetcher.getService(ctx);
        if (sEnableServiceNotFoundWtf && ret == null) {
            // Some services do return null in certain situations, so don't do WTF for them.
            switch (name) {
                case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
                case Context.APP_PREDICTION_SERVICE:
                case Context.INCREMENTAL_SERVICE:
                case Context.ETHERNET_SERVICE:
                case Context.CONTEXTHUB_SERVICE:
                case Context.VIRTUALIZATION_SERVICE:
                case Context.VIRTUAL_DEVICE_SERVICE:
                    return null;
            }
            Slog.wtf(TAG, "Manager wrapper not available: " + name);
            return null;
        }
        return ret;
    }

我们来看一下ServiceFetcher的定义。在CachedServiceFetcher的构造函数中会对sServiceCacheSize进行自增运算。sServiceCacheSizeSystemServiceRegistry中的类变量,代表了system service 的数量。

//frameworks/base/core/java/android/app/SystemServiceRegistry.java
    /**
     * Base interface for classes that fetch services.
     * These objects must only be created during static initialization.
     */
    static abstract interface ServiceFetcher<T> {
        T getService(ContextImpl ctx);
    }
    /**
     * Override this class when the system service constructor needs a
     * ContextImpl and should be cached and retained by that context.
     */
    static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
        private final int mCacheIndex;

        CachedServiceFetcher() {
            // Note this class must be instantiated only by the static initializer of the
            // outer class (SystemServiceRegistry), which already does the synchronization,
            // so bare access to sServiceCacheSize is okay here.
            mCacheIndex = sServiceCacheSize++;//mCacheIndex 决定了这个service存储在mServiceCache中的位置
        }

        @Override
        @SuppressWarnings("unchecked")
        public final T getService(ContextImpl ctx) {
        //这个函数的实现暂时略过,后面再说
        }

        public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
    }

SystemServiceRegistry中,以static代码块的形式注册了system service。后面会讨论,system service注册的过程。这里只需要知道每注册一个system service,都会new一个CachedServiceFetcher,从而使sServiceCacheSize +1。

    static {
        //CHECKSTYLE:OFF IndentationCheck
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() {
            @Override
            public AccessibilityManager createService(ContextImpl ctx) {
                return AccessibilityManager.getInstance(ctx);
            }});
         ...

        sInitializing = true;
        try {
            // Note: the following functions need to be @SystemApis, once they become mainline
            // modules.
            ...
            WifiFrameworkInitializer.registerServiceWrappers();
            ...
        } finally {
            // If any of the above code throws, we're in a pretty bad shape and the process
            // will likely crash, but we'll reset it just in case there's an exception handler...
            sInitializing = false;
        }
    }

sServiceCacheSize的作用就是让ContextImpl可以获取一个system service数量的数组mServiceCache,它里面储存了诸如xxxManager的对象

frameworks/base/core/java/android/app/SystemServiceRegistry.java
    /**
     * Creates an array which is used to cache per-Context service instances.
     * @hide
     */
    public static Object[] createServiceCache() {
        return new Object[sServiceCacheSize];
    }
frameworks/base/core/java/android/app/ContextImpl.java
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();

接下来看一下CachedServiceFetcher.getService(ContextImpl ctx)的实现

frameworks/base/core/java/android/app/SystemServiceRegistry.java

        public final T getService(ContextImpl ctx) {
            final Object[] cache = ctx.mServiceCache;//mServiceCache 是ContextImpl 用以存储system service的数组
            //mServiceInitializationStateArray存储service的初始化状态,
            //STATE_UNINITIALIZED, STATE_INITIALIZING,STATE_READY
            final int[] gates = ctx.mServiceInitializationStateArray;
            boolean interrupted = false;

            T ret = null;

            for (;;) {
                boolean doInitialize = false;
                synchronized (cache) {
                    // Return it if we already have a cached instance.
                    T service = (T) cache[mCacheIndex];//cache[mCacheIndex]就是应该用来存储当前service的位置
                    if (service != null) {
                        ret = service;
                        break; // exit the for (;;)
                    }
                    //如果找不到这个service,那么进行初始化
                    // If we get here, there's no cached instance.

                    // Grr... if gate is STATE_READY, then this means we initialized the service
                    // once but someone cleared it.
                    // We start over from STATE_UNINITIALIZED.
                    // Similarly, if the previous attempt returned null, we'll retry again.
                    if (gates[mCacheIndex] == ContextImpl.STATE_READY
                            || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
                        gates[mCacheIndex] = ContextImpl.STATE_UNINITIALIZED;
                    }

                    // It's possible for multiple threads to get here at the same time, so
                    // use the "gate" to make sure only the first thread will call createService().

                    // At this point, the gate must be either UNINITIALIZED or INITIALIZING.
                    if (gates[mCacheIndex] == ContextImpl.STATE_UNINITIALIZED) {
                        doInitialize = true;
                        gates[mCacheIndex] = ContextImpl.STATE_INITIALIZING;
                    }
                }

                if (doInitialize) {
                    // Only the first thread gets here.
                    // 这里正式进行service初始化

                    T service = null;
                    @ServiceInitializationState int newState = ContextImpl.STATE_NOT_FOUND;
                    try {
                        // This thread is the first one to get here. Instantiate the service
                        // *without* the cache lock held.
                        service = createService(ctx);
                        //createService 在 CachedServiceFetcher中没有实现,他依赖于注册服务时传入的参数
                        //后面会根据WiFiManager进行分析
                        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 (;;)
                }
                // The other threads will wait for the first thread to call notifyAll(),
                // and go back to the top and retry.
                synchronized (cache) {
                    // Repeat until the state becomes STATE_READY or STATE_NOT_FOUND.
                    // We can't respond to interrupts here; just like we can't in the "doInitialize"
                    // path, so we remember the interrupt state here and re-interrupt later.
                    while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
                        try {
                            // Clear the interrupt state.
                            interrupted |= Thread.interrupted();
                            cache.wait();
                        } catch (InterruptedException e) {
                            // This shouldn't normally happen, but if someone interrupts the
                            // thread, it will.
                            Slog.w(TAG, "getService() interrupted");
                            interrupted = true;
                        }
                    }
                }
            }
            if (interrupted) {
                Thread.currentThread().interrupt();
            }
            return ret;
        }

下面来看WifiManager是怎么注册的,它的注册是在WifiFrameworkInitializer.registerServiceWrappers()中完成的

packages/modules/Wifi/framework/java/android/net/wifi/WifiFrameworkInitializer.java

    public static void registerServiceWrappers() {
        SystemServiceRegistry.registerContextAwareService(
                Context.WIFI_SERVICE,
                WifiManager.class,
                (context, serviceBinder) -> {
                    if (!context.getPackageManager().hasSystemFeature(
                            PackageManager.FEATURE_WIFI)) {
                        return null;
                    }
                    IWifiManager service = IWifiManager.Stub.asInterface(serviceBinder);
                    return new WifiManager(context, service, getInstanceLooper());
                }
        );
        ...
    }
frameworks/base/core/java/android/app/SystemServiceRegistry.java

    public static <TServiceClass> void registerContextAwareService(
            @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
            @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) {
        ensureInitializing("registerContextAwareService");
        Preconditions.checkStringNotEmpty(serviceName);
        Objects.requireNonNull(serviceWrapperClass);
        Objects.requireNonNull(serviceProducer);

        registerService(serviceName, serviceWrapperClass,
                new CachedServiceFetcher<TServiceClass>() {
                    @Override
                    public TServiceClass createService(ContextImpl ctx)
                            throws ServiceNotFoundException {
                        return serviceProducer.createService(
                                ctx.getOuterContext(),
                                //获取IBinder对象
                                ServiceManager.getServiceOrThrow(serviceName));
                    }});
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值