Android中服务管理相关流程getSystemService

来源:互联网 发布:ubuntu uefi 双硬盘 编辑:程序博客网 时间:2024/06/05 17:37
我们经常会使用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();
}});

0 0
原创粉丝点击