浅析getSystemService获取系统服务

所谓系统服务是指可以使用getSystemService方法获取的服务,所谓客户端服务是指应该程序提供的自定义服务。

那么getSystemService方法到底有哪些服务呢?我们来看看getSystemService的实现,getSystemService的实现在ContextImpl中。

public Object getSystemService(String name) {
    ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
    return fetcher == null ? null : fetcher.getService(this);
}

SYSTEM_SERVICE_MAP是何许人也,我们来继续看代码。

private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
            new HashMap<String, ServiceFetcher>();

可以知道,它是一个HashMap,我们通过name来获取到ServiceFetcher对象,如果获取到的ServiceFetcher对象不为空,就通过ServiceFetcher对象的getService来获取到指定的服务。

首先我们要解决一个问题,那就是SYSTEM_SERVICE_MAP这个HashMap中的ServiceFetcher对象是在什么时候被添加进去的。

我们可以看到ContextImpl里面有一个静态块,也就是说这个类的字节码被载入内存的时候就把相应的服务都注册进去类,那么我们后面就可以找到相应的服务了。

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

    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(ctx.getOuterContext(),
                        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.getOuterContext(),
                  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.getContentResolver(), 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(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(ctx);
            }});

    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(ctx.getOuterContext(), service);
            }});

    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() {
            Display mDefaultDisplay;
            public Object getService(ContextImpl ctx) {
                Display display = ctx.mDisplay;
                if (display == null) {
                    if (mDefaultDisplay == null) {
                        DisplayManager dm = (DisplayManager)ctx.getOuterContext().
                                getSystemService(Context.DISPLAY_SERVICE);
                        mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
                    }
                    display = mDefaultDisplay;
                }
                return new WindowManagerImpl(display);
            }});

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

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

    registerService(CAMERA_SERVICE, new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
            return new CameraManager(ctx);
        }
    });

    registerService(PRINT_SERVICE, new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
            IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
            IPrintManager service = IPrintManager.Stub.asInterface(iBinder);
            return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(),
                    UserHandle.getAppId(Process.myUid()));
        }});

    registerService(CONSUMER_IR_SERVICE, new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
            return new ConsumerIrManager(ctx);
        }});
}

从上面我们也可以看到我们可以使用getSystemService可以获取的所有系统服务。
下面我们就将这些服务名进行列举,我们使用getSystemService(name),name为String类型。

public static final String POWER_SERVICE = "power";
public static final String WINDOW_SERVICE = "window";
public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
public static final String ACCOUNT_SERVICE = "account";
public static final String ACTIVITY_SERVICE = "activity";
public static final String ALARM_SERVICE = "alarm";
public static final String NOTIFICATION_SERVICE = "notification";
public static final String ACCESSIBILITY_SERVICE = "accessibility";
public static final String CAPTIONING_SERVICE = "captioning";
public static final String KEYGUARD_SERVICE = "keyguard";
public static final String LOCATION_SERVICE = "location";
public static final String COUNTRY_DETECTOR = "country_detector";
public static final String SEARCH_SERVICE = "search";
public static final String SENSOR_SERVICE = "sensor";
public static final String STORAGE_SERVICE = "storage";
public static final String WALLPAPER_SERVICE = "wallpaper";
public static final String VIBRATOR_SERVICE = "vibrator";
public static final String STATUS_BAR_SERVICE = "statusbar";
public static final String CONNECTIVITY_SERVICE = "connectivity";
public static final String UPDATE_LOCK_SERVICE = "updatelock";
public static final String NETWORKMANAGEMENT_SERVICE = "network_management";
/** {@hide} */
public static final String NETWORK_STATS_SERVICE = "netstats";
/** {@hide} */
public static final String NETWORK_POLICY_SERVICE = "netpolicy";
public static final String WIFI_SERVICE = "wifi";
public static final String WIFI_P2P_SERVICE = "wifip2p";
public static final String NSD_SERVICE = "servicediscovery";
public static final String AUDIO_SERVICE = "audio";
public static final String MEDIA_ROUTER_SERVICE = "media_router";
public static final String TELEPHONY_SERVICE = "phone";
public static final String CLIPBOARD_SERVICE = "clipboard";
public static final String INPUT_METHOD_SERVICE = "input_method";
public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
public static final String APPWIDGET_SERVICE = "appwidget";
public static final String BACKUP_SERVICE = "backup";
public static final String DROPBOX_SERVICE = "dropbox";
public static final String DEVICE_POLICY_SERVICE = "device_policy";
public static final String UI_MODE_SERVICE = "uimode";
public static final String DOWNLOAD_SERVICE = "download";
public static final String NFC_SERVICE = "nfc";
public static final String BLUETOOTH_SERVICE = "bluetooth";
/** @hide */
public static final String SIP_SERVICE = "sip";
public static final String USB_SERVICE = "usb";
/** @hide */
public static final String SERIAL_SERVICE = "serial";
public static final String INPUT_SERVICE = "input";
public static final String DISPLAY_SERVICE = "display";
public static final String USER_SERVICE = "user";
public static final String APP_OPS_SERVICE = "appops";
public static final String CAMERA_SERVICE = "camera";
public static final String PRINT_SERVICE = "print";
public static final String CONSUMER_IR_SERVICE = "consumer_ir";

这些名称的定义在Context类中。

从上面我们可以看到registerService将指定name的ServiceFetcher放到HashMap当中。
下面我们来看看registerService方法的实现,它在ContextImpl中。

private static int sNextPerContextServiceCacheIndex = 0;
private static void registerService(String serviceName, ServiceFetcher fetcher) {
    if (!(fetcher instanceof StaticServiceFetcher)) {
        fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
    }
    SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}

如果fetcher不是StaticServiceFetcher类型的实例,也就是静态ServiceFetcher实例,就将sNextPerContextServiceCacheIndex自加,然后将它赋值给fetcher中的mContextCacheIndex。
接着就将对应的serviceName和ServiceFetcher放入Map中。

下面我们就来看看ServiceFetcher这个类的getService方法。

/*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 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);
                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() will handle locking and caching.
     */
    public Object createService(ContextImpl ctx) {
        throw new RuntimeException("Not implemented");
    }
}

思路好像有些混乱。下面梳理梳理。
1、在ContextImpl中有一个mServiceCache,它用来缓存已经注册的服务
final ArrayList mServiceCache = new ArrayList();

2、在ContextImpl中有sNextPerContextServiceCacheIndex用来为缓存服务指定索引。
private static int sNextPerContextServiceCacheIndex = 0;

3、在ServiceFetcher中有一个mContextCacheIndex来存放ServiceFetcher这个服务在mServiceCache缓存中对应的索引值。
int mContextCacheIndex = -1;

4、注册服务。
在注册服务会將sNextPerContextServiceCacheIndex赋值给fetcher对象的mContextCacheIndex,然后自加,也就是说指定serviceName的ServiceFetcher会缓存在mServiceCache的mContextCacheIndex位置。
这个通过sNextPerContextServiceCacheIndex不但的递增来为指定名称的ServiceFetcher对象在mServiceCache中指定一个唯一的索引值mContextCacheIndex。

private static void registerService(String serviceName, ServiceFetcher fetcher) {
    if (!(fetcher instanceof StaticServiceFetcher)) {
        fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
    }
    SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}

5、获取服务,通过指定服务名在SYSTEM_SERVICE_MAP中找到指定的ServiceFetcher,然后通过getService获取到指定的服务。

public Object getService(ContextImpl ctx) {
    ArrayList<Object> cache = ctx.mServiceCache;
    Object service;
    synchronized (cache) {
        if (cache.size() == 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);
            if (service != null) {
                return service;
            }
        }
        service = createService(ctx);
        cache.set(mContextCacheIndex, service);
        return service;
}

首先得到ContexImpl中的缓存服务列表mServiceCache,如果列表为空,就把这个列表内容置空,否在,通过mContextCacheIndex,也就是上面指定的服务在缓存中对应的索引来找到对应的服务,如果没有找到,就将创建服务,然后将这个服务添加到缓存类表的指定位置。

下面我们来看看createService(ctx)的实现。我们以下面这个为例。

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

我们可以看到实质是通过ServiceManager.getService(ALARM_SERVICE)获取对应的Binder,得到对应的本地代理对象,然后把它封装到AlaramManager中,这样我们最终通过getSystemService就会获取到对应的Manager,这也是为什么我们通过getSystemService可以获取到对应服务的管理者的原因。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值