編輯:關於Android編程
在開發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()函數來構造服務管理對象,該函數是一個抽象函數,在注冊每一個服務管理對象時實現該函數,在該函數裡構造對應的服務管理對象。
DrawerLayout組件同樣是V4包中的組件,也是直接繼承於ViewGroup類,所以這個類也是一個容器類。使用DrawerLayout可以輕松的實現抽屜效果,使用D
概述項目快速迭代過程中,不可避免的出現BUG,Android線上出現問題,通常需要發版解決。緊急發版,用戶不一定升級,強制升級又不友好,有什麼更好的解決方案呢?這就用到了
為了練練手,增長逆向分析的知識,本次博客打算分析一下某酒店APP的登陸請求。這次的逆向分析還是以網絡請求為例,通過分析其登陸請求數據的加解密原理,將請求數據從密文轉換成明
在前面多篇文章中,都有提到ActivityManagerService,它是在系統啟動時加載的一個服務線程,運行於system_server進程中,主要負責管理系統中的A