我們知道一個(gè)應(yīng)用的Context個(gè)數(shù)是Activity個(gè)數(shù)+Service個(gè)數(shù)+1
當(dāng)我們希望獲取到系統(tǒng)服務(wù)時(shí),可以調(diào)用Context的getSystemService方法,如獲取到ActivityManager:
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
那么getSystemService又是怎么工作的呢?
Activity是一個(gè)Context,他調(diào)用getSystemService時(shí),會(huì)調(diào)用到Context的包裝類ContextWrapper的getSystemService方法,如下:
@Overridepublic Object getSystemService(String name) { return mBase.getSystemService(name);}
mBase是Context的實(shí)現(xiàn)類ContextImpl,很明顯ContextWrapper又會(huì)委托ContextImpl去實(shí)現(xiàn)具體邏輯。
我們跟進(jìn)ContextImpl中的getSystemService方法,如下:
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
其內(nèi)部是調(diào)用了SystemServiceRegistry的getSystemService方法,這時(shí)獲取系統(tǒng)服務(wù)的過程就轉(zhuǎn)移到了SystemServiceRegistry了。
我們看到SystemServiceRegistry的getSystemService方法即可,如下:
/**
* Gets a system service from a given context.
*/
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
這好像還看不出太多的信息。SYSTEM_SERVICE_FETCHERS.get(name)是什么?
SYSTEM_SERVICE_FETCHERS是一個(gè)存儲(chǔ)ServiceFetcher的HashMap
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
我們先不管SYSTEM_SERVICE_FETCHERS.get(name)返回值是什么,
先發(fā)現(xiàn)ServiceFetcher是什么時(shí)候存儲(chǔ)到SYSTEM_SERVICE_FETCHERS里的。
SystemServiceRegistry中有一段靜態(tài)代碼塊長(zhǎng)這樣:
static {
//代碼省略
registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
new CachedServiceFetcher<ActivityManager>() {
@Override
public ActivityManager createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
registerService(Context.ALARM_SERVICE, AlarmManager.class,
new CachedServiceFetcher<AlarmManager>() {
@Override
public AlarmManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
//代碼省略
}
靜態(tài)代碼塊只在虛擬機(jī)第一次加載類的時(shí)候執(zhí)行。
靜態(tài)代碼塊中調(diào)用registerService方法來注冊(cè)系統(tǒng)服務(wù)的,而registerService方法內(nèi)部是將key和value存進(jìn)去SYSTEM_SERVICE_FETCHERS,找到了,如下:
/**
* Statically registers a system service with the context.
* This method must be called during static initialization only.
*/
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
可以看到存進(jìn)了serviceFetcher,而serviceName就是我們傳進(jìn)的字符串,比如 Context.ACTIVITY_SERVICE
我們分析ActivityManager即可,在注冊(cè)ActivityManager時(shí)傳進(jìn)registerService方法的是CachedServiceFetcher,那么我們跟進(jìn)CachedServiceFetcher看看。
/**
* 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;
public CachedServiceFetcher() {
mCacheIndex = sServiceCacheSize++;
}
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
// Fetch or create the service.
Object service = cache[mCacheIndex];
if (service == null) {
service = createService(ctx);
cache[mCacheIndex] = service;
}
return (T)service;
}
}
public abstract T createService(ContextImpl ctx);
}
CachedServiceFetcher實(shí)現(xiàn)了ServiceFetcher接口,這個(gè)getService方法是在一開始的getSystemService方法中觸發(fā),如下
return fetcher != null ? fetcher.getService(ctx) : null;
喔,原來是通過ServiceFetcher來獲取系統(tǒng)服務(wù)的。
到這里我們分析CachedServiceFetcher可以知道,當(dāng)?shù)谝淮潍@取服務(wù)的時(shí)候,會(huì)調(diào)用createService去創(chuàng)建實(shí)例,然后將服務(wù)對(duì)象添加進(jìn)緩存。下次再取時(shí)就直接從緩存中獲取了。其實(shí)這是一種使用容器來實(shí)現(xiàn)的單例模式。
最后總結(jié)一下:當(dāng)我們調(diào)用Context的getSystemService方法獲取服務(wù)時(shí),會(huì)轉(zhuǎn)到SystemServiceRegistry類的getSystemService方法,在這個(gè)getSystemService方法中,根據(jù)key,也就是我們傳入的字符串,比如Context.ACTIVITY_SERVICE。根據(jù)傳入的key從SYSTEM_SERVICE_FETCHERS這個(gè)HashMap中獲取到ServiceFetcher實(shí)例,再調(diào)用ServiceFetcher實(shí)例的getService方法獲取到系統(tǒng)服務(wù)對(duì)象。如果是第一次獲取系統(tǒng)服務(wù)的話,會(huì)調(diào)用ServiceFetcher的createService方法去創(chuàng)建系統(tǒng)服務(wù)實(shí)例并將其加入緩存列表,之后再次獲取就是從緩存中取出了。
而靜態(tài)代碼塊又是怎么回事?其實(shí)就是為每一個(gè)系統(tǒng)服務(wù)執(zhí)行了以下的代碼嘛
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
SystemServiceRegistry中的靜態(tài)代碼塊只會(huì)執(zhí)行一次,告訴系統(tǒng),我是有這些服務(wù)的,將一些key和value添加進(jìn)HashMap。就是一些初始化的工作。而并沒有真正去創(chuàng)建系統(tǒng)服務(wù)對(duì)象,因?yàn)閏reateService還沒有被調(diào)用啊
好了,以上就是Context的getSystemService方法的工作過程分析。從中我學(xué)到了原來還有這種使用容器的單例模式。