您的位置:首页 > 移动开发 > Android开发

Android之getSystemService方法实现详解

2013-05-15 17:06 417 查看
一、概述

Android应用层获取系统java层的service, 用到getSystemService这个API。getSystemService方法定义于context类, 但context类是一个抽象类,它的具

体实现在contextImpl类中, getSystemService方法在contextImpl类中的代码如下:

@Override

public Object getSystemService(String name) {

ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);

return fetcher == null ? null : fetcher.getService(this);

}

二、ServiceFetcher类

/*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) {

// Initialize the cachevector on first access.

// At this pointsNextPerContextServiceCacheIndex

// is the number ofpotential services that are

// cached per-Context.

for (int i = 0; i <sNextPerContextServiceCacheIndex; i++) {

cache.add(null);

}

} else {

service =cache.get(mContextCacheIndex);

if (service != null) {

return service;

}

}

service = createService(ctx);

cache.set(mContextCacheIndex,service);

return service;

}

}

/**

* Override this to create a new per-Context instance of the

* service. getService() willhandle locking and caching.

*/

public Object createService(ContextImpl ctx) {

throw new RuntimeException("Not implemented");

}

}

ServiceFetcher类是一个辅助类,用于获取系统中的service, 这个类比较简单,只定义了getService和createService方法。每个java层的service, 如wifiservice,

activitymanagerservice等都会建立一个ServiceFetcher类的对象,这个对象会重载createService方法,并且这个对象会通过contextImpl类中的registerService

方法添加到SYSTEM_SERVICE_MAP(详见下文)这个hashmap变量中。

registerService方法代码如下:

private static void registerService(StringserviceName, ServiceFetcher fetcher) {

if (!(fetcher instanceofStaticServiceFetcher)) {

fetcher.mContextCacheIndex =sNextPerContextServiceCacheIndex++;

}

SYSTEM_SERVICE_MAP.put(serviceName,fetcher);

}

在contextImpl类的静态块中会完成所有java层的service添加到SYSTEM_SERVICE_MAP的操作, 代码如下:

static {

registerService(ACCESSIBILITY_SERVICE,new ServiceFetcher() {

public ObjectgetService(ContextImpl ctx) {

returnAccessibilityManager.getInstance(ctx);

}});

registerService(ALARM_SERVICE, newStaticServiceFetcher() {

public ObjectcreateStaticService() {

IBinder b =ServiceManager.getService(ALARM_SERVICE);

IAlarmManager service =IAlarmManager.Stub.asInterface(b);

return newAlarmManager(service);

}});

……

}

要明白ServiceFetcher的作用,只要明白createService和getService方法。createService方法本身没有实现,需要重载来实现的,下面是一个重载的例子。

registerService(ALARM_SERVICE, new StaticServiceFetcher() {

publicObject createStaticService() {

IBinder b = ServiceManager.getService(ALARM_SERVICE);

IAlarmManager service = IAlarmManager.Stub.asInterface(b);

return new AlarmManager(service);

}});

如果读者对android的binder机制比较熟悉的话,很快就明白这几行代码的目的是获得AlarmManagerService的代理对象,然后以这个代理对象为参数构造

AlarmManager对象,也就是说createService方法最后返回了AlarmManger对象。至于getService方法,阅读一下getService方法的源码,不难看出该方法先在

一个用于cache功能的arraylist中查找service,如果没有找到,就通过createSystem方法创建一个,并返回。

由上可知,ServiceFetcher的作用是通过createService方法获得xxxManager对象,然后通过getService方法返回给上层。

三、SYSTEM_SERVICE_MAP变量

SYSTEM_SERVICE_MAP是一个hashmap变量,存放的是service名称与service对应的servicefetcher

private static final HashMap<String,ServiceFetcher> SYSTEM_SERVICE_MAP =

new HashMap<String,ServiceFetcher>();

四、 总结

好了,了解以上内容后,我们再来看getSystemService方法的实现,

@Override

public Object getSystemService(String name) {

ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);

return fetcher == null ? null : fetcher.getService(this);

}

首先,通过传入的service name从SYSTEM_SERVICE_MAP这个hashmap中获得一个ServiceFetcher对象,这个对象同一个service绑定。

然后,通过上面获得的ServiceFetcher的getService方法取得一个xxxManager对象(每个java层的service都实现了一个xxxManager类,这个类为该service

封装API供应用层调用)。

这样,应用层就可以通过这个xxxManager来使用对应的service提供的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: