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

Android上下文服务管理查询过程

2013-12-05 16:34 162 查看
在开发Android应用程序时,如果需要使用系统提供的服务,可以通过服务名称调用山下文的getSystemService(String name)来获取服务管理者,那么该函数是如何实现服务查询的呢?

frameworks\base\core\java\android\app\ContextImpl.java

public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
SYSTEM_SERVICE_MAP被定义为HashMap类型变量,该变量以服务名称—ServiceFetcher对象这种键值对的方式保存了一系列系统服务管理对象,该变量定义为静态类型,因此在ContextImpl类加载时,该变量就已经创建,同时在ContextImpl类中通过Static块语句来初始化SYSTEM_SERVICE_MAP变量:

static {
registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
return AccessibilityManager.getInstance(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);
}});

if (SystemProperties.getBoolean("universe_ui_support",false)) {
registerService(THEME_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(THEME_SERVICE);
IThemeManager service = IThemeManager.Stub.asInterface(b);
return new ThemeManager(ctx, service);
}});
}

registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});

registerService(ALARM_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service);
}});

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(CLIPBOARD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ClipboardManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler());
}});

registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
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(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(INPUT_METHOD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return InputMethodManager.getInstance(ctx);
}});

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)));
}
});

registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
final Context outerContext = ctx.getOuterContext();
return new NotificationManager(
new ContextThemeWrapper(outerContext,
Resources.selectSystemTheme(0,
outerContext.getApplicationInfo().targetSdkVersion,
com.android.internal.R.style.Theme_Dialog,
com.android.internal.R.style.Theme_Holo_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
ctx.mMainThread.getHandler());
}});

registerService(NSD_SERVICE, new ServiceFetcher() {
@Override
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(NSD_SERVICE);
INsdManager service = INsdManager.Stub.asInterface(b);
return new NsdManager(ctx.getOuterContext(), service);
}});

// Note: this was previously cached in a static variable, but
// constructed using mMainThread.getHandler(), so converting
// it to be a regular Context-cached service...
registerService(POWER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(POWER_SERVICE);
IPowerManager service = IPowerManager.Stub.asInterface(b);
return new PowerManager(service, ctx.mMainThread.getHandler());
}});

registerService(SEARCH_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new SearchManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler());
}});

registerService(SENSOR_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new SystemSensorManager(ctx.mMainThread.getHandler().getLooper());
}});

registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new StatusBarManager(ctx.getOuterContext());
}});

registerService(STORAGE_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
try {
return new StorageManager(ctx.mMainThread.getHandler().getLooper());
} catch (RemoteException rex) {
Log.e(TAG, "Failed to create StorageManager", rex);
return null;
}
}});
registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new TelephonyManager(ctx.getOuterContext());
}});

registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
public Object createStaticService() {
IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
}});

registerService(UI_MODE_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new UiModeManager();
}});

registerService(USB_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(USB_SERVICE);
return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
}});

registerService(SERIAL_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(SERIAL_SERVICE);
return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
}});

registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new SystemVibrator();
}});

registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);

registerService(WIFI_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(WIFI_SERVICE);
IWifiManager service = IWifiManager.Stub.asInterface(b);
return new WifiManager(service, ctx.mMainThread.getHandler());
}});

registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
return new WifiP2pManager(service);
}});

registerService(WINDOW_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
}});
}
在该Static块语句里,通过调用registerService函数向SYSTEM_SERVICE_MAP哈希变量中添加服务管理对象:

private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
首先通过服务名称从SYSTEM_SERVICE_MAP哈希表中查找出服务对应的ServiceFetcher对象,然后调用ServiceFetcher对象的getService函数来获取服务管理Manager对象

public final Object getService(ContextImpl unused) {
synchronized (StaticServiceFetcher.this) {
Object service = mCachedInstance;
if (service != null) {
return service;
}
return mCachedInstance = createStaticService();
}
}
这里以单例模式获取服务管理对象,如果变量mCachedInstance为空,则表示系统还未使用过该服务,则调用createStaticService()函数来构造服务管理对象,该函数是一个抽象函数,在注册每一个服务管理对象时实现该函数,在该函数里构造对应的服务管理对象。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐