Android中服務管理相關流程getSystemService

我們經常會使用context來獲取服務實例,完成某些特定的功能。
辣麼他的大致是什麼樣的流程呢?下面跟蹤一下source code。  代碼基於Android 5.1.1

一、相關的類文件:
framework/base/core/java/android/app/ContextImpl.java
二、相關流程
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;  
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
從上面getSystemService方法中看到,首先是從SYSTEM_SERVICE_MAP中獲取ServiceFetcher對象,然後調用ServiceFetcher對象的getService方法獲取管理的service.

這裏的SYSTEM_SERVICE_MAP  是一個HashMap,鍵值對的方式存儲service相關信息。
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();
SYSTEM_SERVICE_MAP  是static 因此在加載ContextImpl.java這個類的時候,就初始化了。
下面用的是一個靜態初始化塊將service添加到對應的SYSTEM_SERVICE_MAP  中:
static {
registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
return AccessibilityManager.getInstance(ctx);
}});
 
registerService(CAPTIONING_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
return new CaptioningManager(ctx);
}});
 
registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
IAccountManager service = IAccountManager.Stub.asInterface(b);
return new AccountManager(ctx, service);
}});
 
registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
 
registerService(ALARM_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
 
registerService(AUDIO_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new AudioManager(ctx);
}});
 
registerService(MEDIA_ROUTER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new MediaRouter(ctx);
}});
 
registerService(BLUETOOTH_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new BluetoothManager(ctx);
}});
 
registerService(HDMI_CONTROL_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(HDMI_CONTROL_SERVICE);
return new HdmiControlManager(IHdmiControlService.Stub.asInterface(b));
}});
 
registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ClipboardManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler());
}});
 
registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
}});
 
registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
return new CountryDetector(ICountryDetector.Stub.asInterface(b));
}});
 
registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
}});
 
registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
}});
 
registerService(BATTERY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new BatteryManager();
}});
 
registerService(NFC_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new NfcManager(ctx);
}});
 
registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
return createDropBoxManager();
}});
 
registerService(INPUT_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
return InputManager.getInstance();
}});
 
registerService(DISPLAY_SERVICE, new ServiceFetcher() {
@Override
public Object createService(ContextImpl ctx) {
return new DisplayManager(ctx.getOuterContext());
}});
 
registerService(INPUT_METHOD_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
return InputMethodManager.getInstance();
}});
 
registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return TextServicesManager.getInstance();
}});
 
registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
// TODO: why isn't this caching it? It wasn't
// before, so I'm preserving the old behavior and
// using getService(), instead of createService()
// which would do the caching.
return new KeyguardManager();
}});
 
registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
}});
 
registerService(LOCATION_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
return new LocationManager(ctx, ILocationManager.Stub.asInterface(b));
}});
 
registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
@Override
public Object createService(ContextImpl ctx) {
return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
ServiceManager.getService(NETWORK_POLICY_SERVICE)));
}
});

三、關係結構
這裏先來研究一下ServiceFetcher這個內部類
/**
* Override this class when the system service constructor needs a
* ContextImpl. Else, use StaticServiceFetcher below.
*/
/*package*/ static class ServiceFetcher {
int mContextCacheIndex = -1;
 
/**
* Main entrypoint; only override if you don't need caching.
*/
public Object getService(ContextImpl ctx) {
//先從緩存中獲取,如果沒有則創建,並緩存起來。
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
//這段代碼是第一次調用的時候會執行,sNextPerContextServiceCacheIndex =0 貌似沒什麼意義啊?!
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);//以當前ServiceFetcher對象的mContextCacheIndex獲取service
if (service != null) {
return service;
}
}
//如果緩存沒有則創建service實例,緩存起來並返回。
service = createService(ctx); //crateService方法會被重寫,從registerService方法中可以看到
cache.set(mContextCacheIndex, service);
return service;
}
}
 
/**
* Override this to create a new per-Context instance of the
* service. getService() will handle locking and caching.
*/
public Object createService(ContextImpl ctx) {
throw new RuntimeException("Not implemented");//從這裏可以看出該方法必須被重寫
}
}
ServiceFetcher類中mContextCacheIndex是存儲在list中的index,index的值是在registerService的時候賦值的。
mServiceCache 屬於ContextImpl的全局變量,應該是用於緩存service的,當我們在程序中使用到了某個service,它就會緩存創建出來的這個service,以供其他的使用、。
從getService的方法邏輯我們就可以看出來。

另外,大家可以看到在static靜態初始化塊中,、,ServiceFetcher並不是全部都重寫了createService方法,而是直接重寫了getService返回了service
實例,也就是說不緩存該service,爲啥呢? 具體的原因在代碼後面有註釋。google大佬說以前都沒有緩存,現在也不緩存.....
registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
// TODO: why isn't this caching it? It wasn't
// before, so I'm preserving the old behavior and
// using getService(), instead of createService()
// which would do the caching.
return new KeyguardManager();
}});

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章