Android SystemService解析

在日常使用中,我们一般获取系统的服务都是通过Context类来获取,然而在不同的activity中获取到的服务有时是同一个对象,而有时又是不同的对象。这是为什么呢,首先一般获取服务的方法为

public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name);

那么我们来看一下获取的具体流程和系统如何管理的吧。

首先从最常见的activity开始分析

// Activity.java

@Override
public Object getSystemService(@ServiceName @NonNull String name) {
    if (getBaseContext() == null) {
        throw new IllegalStateException(
                "System services not available to Activities before onCreate()");
    }
	//如果获取的是常用的service则直接返回
    if (WINDOW_SERVICE.equals(name)) {
        return mWindowManager;
    } else if (SEARCH_SERVICE.equals(name)) {
        ensureSearchManager();
        return mSearchManager;
    }
    //没找到交给父类
    return super.getSystemService(name);
}

activity作为一个ContextThemeWrapper对象(有界面和主题)

// ContextThemeWrapper.java

@Override
public Object getSystemService(String name) {
	//如果是布局加载器者返回
    if (LAYOUT_INFLATER_SERVICE.equals(name)) {
        if (mInflater == null) {
            mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
        }
        return mInflater;
    }
    //调用ContextWrapper中的mBase区执行获取服务的操作,即为ContextImpl对象
    return getBaseContext().getSystemService(name);
}

熟悉Context的小伙伴应该知道Android中的Context方法的具体实现都会交给ContextImpl去进行实现(之后补充)

// ContextImpl.java

@Override
public Object getSystemService(String name) {
	//通过静态方法获取
    return SystemServiceRegistry.getSystemService(this, name);
}

这里的SYSTEM_SERVICE_FETCHERS是一个以服务名称为key,ServiceFetcher为value的map容器。

// SystemServiceRegistry.java

private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = 
	new HashMap<String, ServiceFetcher<?>>();
public static Object getSystemService(ContextImpl ctx, String name) {
	// 通过传入的服务名称获取ServiceFetcher对象,若不为空则获取其中的具体服务,为空则表示系统中并没有这个服务
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

而SYSTEM_SERVICE_FETCHERS的初始化是写在静态代码块中的,所以当类被加载的时候就会进行map的初始化

// SystemServiceRegistry.java

static {
   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);
        }});
        
        ...
}

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
     // 服务类型 - 服务名称
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    // 服务名称 - ServiceFetcher
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

而ServiceFetcher是一个抽象的接口,具体的实现取决于不同服务的需求,即可以使一个ContextImpl对应一个服务或者一个单例的服务。

// SystemServiceRegistry.java 

static abstract interface ServiceFetcher<T> {
    T getService(ContextImpl ctx);
}

对于单例的服务则对应于StaticServiceFetcher的抽象类

// SystemServiceRegistry.java 

static abstract class StaticServiceFetcher<T> implements ServiceFetcher<T> {
	//服务的单例缓存
    private T mCachedInstance;
    @Override
    public final T getService(ContextImpl ctx) {
        synchronized (StaticServiceFetcher.this) {
            if (mCachedInstance == null) {
                try {
                    mCachedInstance = createService();
                } catch (ServiceNotFoundException e) {
                    onServiceNotFound(e);
                }
            }
            return mCachedInstance;
        }
    }
    //第一次获取时如何创建服务
    public abstract T createService() throws ServiceNotFoundException;
}

CachedServiceFetcher 不同context对应不同的服务

// SystemServiceRegistry.java 

static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
	//不同类型的服务对应一个index,方便在context对应的服务cache中定位
    private final int mCacheIndex;
    public CachedServiceFetcher() {
    	//sServiceCacheSize表示cache服务类型的总个数,表示ContextImpl中cache的大小
        mCacheIndex = sServiceCacheSize++;
    }
    @Override
    @SuppressWarnings("unchecked")
    public final T getService(ContextImpl ctx) {
    	//获取ContextImpl中cache容器,这样使得不同的服务对象存放在自己的容器中,在自己被回收时一并被回收,防止内存泄漏
        final Object[] cache = ctx.mServiceCache;
        synchronized (cache) {
            // Fetch or create the service.
            Object service = cache[mCacheIndex];
            if (service == null) {
                try {
                    service = createService(ctx);
                    cache[mCacheIndex] = service;
                } catch (ServiceNotFoundException e) {
                    onServiceNotFound(e);
                }
            }
            return (T)service;
        }
    }
    public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
}

在ContextImpl中创建cache

// ContextImpl.java
final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();


// SystemServiceRegistry.java
public static Object[] createServiceCache() {
    return new Object[sServiceCacheSize];
}

// TODO 整体结构图和UML图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值