在日常使用中,我们一般获取系统的服务都是通过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图