天天看点

Android中ContextImpl源码分析(二)

1、背景

在前一篇文章中我们分析了Android系统中的Context类及其子类相关关系,以及各种Context子类的创建过程,大家有兴趣的可以去了解一下Android中Context源码分析(一),今天我们要和大家说的就是Context的具体实现ContextImpl类。

2、源码分析

Context在Android中的地位是举足轻重的,但是其是一个抽象类,当中定义了许多和系统相关的抽象方法和普通方法,那它的具体实现者是谁呢?就是我们今天要说的ContextImpl对象,但是Android又不允许我们直接去访问该类,所以Android又提供了Context的子类ContextWrapper以供用户访问,该类只是一个对外对接的封装类,其内部还是调用ContextImpl类处理相关问题。

我们接下来直接分析ContextImpl源码,由于ContextImpl的源码特别多,而且实现了Context中的绝大部分方法,所以在此我们就只看注册系统服务的相关源码。

//ActivityManager/ActivityManagerService
registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                }});


//UsbManager/UsbService
registerService(USB_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(USB_SERVICE);
                    return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
                }});


//WindowManagerImpl/WindowManagerService
registerService(WINDOW_SERVICE, new ServiceFetcher() {
                Display mDefaultDisplay;
                public Object getService(ContextImpl ctx) {
                    Display display = ctx.mDisplay;
                    if (display == null) {
                        if (mDefaultDisplay == null) {
                            DisplayManager dm = (DisplayManager)ctx.getOuterContext().
                                    getSystemService(Context.DISPLAY_SERVICE);
                            mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
                        }
                        display = mDefaultDisplay;
                    }
                    return new WindowManagerImpl(display);
                }});

//特殊的方式获取到PackageManager
public PackageManager getPackageManager() {
        if (mPackageManager != null) {
            return mPackageManager;
        }

        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }

        return null;
    }

//......
           

还有很多的系统相关类都在ContextImpl类中被注册,大家有兴趣的话可以去了解一下,在这里可以看到所有的注册都是通过registerService方法进行的,我们进入该方法。

//存储所有系统服务的HashMap
    private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
            new HashMap<String, ServiceFetcher>();

    private static int sNextPerContextServiceCacheIndex = ;

    private static void registerService(String serviceName, ServiceFetcher fetcher) {
        if (!(fetcher instanceof StaticServiceFetcher)) {
            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
        }
        //add
        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    }
           

那如果我们想使用这样的系统服务应该如何取出呢?

public Object getSystemService(String name) {
        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
        return fetcher == null ? null : fetcher.getService(this);
    }
           

好啦,相信大家对Android如何注册系统服务和获取服务已经熟悉啦,那我们就在看一下ServiceFetcher及其子类StaticServiceFetcher,作为一个补充吧,毕竟存储系统的服务的HashMap

//ServiceFetcher
static class ServiceFetcher {
        int mContextCacheIndex = -;

        public Object getService(ContextImpl ctx) {
            ArrayList<Object> cache = ctx.mServiceCache;
            Object service;
            synchronized (cache) {
                if (cache.size() == ) {
                    for (int i = ; i < sNextPerContextServiceCacheIndex; i++) {
                        cache.add(null);
                    }
                } else {
                    service = cache.get(mContextCacheIndex);
                    if (service != null) {
                        return service;
                    }
                }
                service = createService(ctx);
                cache.set(mContextCacheIndex, service);
                return service;
            }
        }

         //createService
        public Object createService(ContextImpl ctx) {
            throw new RuntimeException("Not implemented");
        }
}

//StaticServiceFetcher
abstract static class StaticServiceFetcher extends ServiceFetcher {
        private Object mCachedInstance;

        @Override
        public final Object getService(ContextImpl unused) {
            synchronized (StaticServiceFetcher.this) {
                Object service = mCachedInstance;
                if (service != null) {
                    return service;
                }
                return mCachedInstance = createStaticService();
            }
        }

        //createStaticService
        public abstract Object createStaticService();
}
           

好啦,我们这里对ContextImpl就简单的分析到这里啦。