android 7.0 Activity 的getSystemService()
2017-05-11 14:25
381 查看
当我们的应用需要调用系统服务时,我们是通过getSystemService()方法来获取系统服务并直接调用。系统服务的进程和当前应用程序的进程肯定是不同的,不同的进程间是不能直接进行通信的。那为什么可以这个方法获取直接调用呢?我们来看看到底是怎么实现的。 getSystemService()方法是在ContextImpl中,因为Activity时的Context对象的实现类是ContextImpl。
frameworks\base\core\java\android\app\ContextImpl.java->getSystemService():
@Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }
再看看SystemServiceRegistry.java。
frameworks\base\core\java\android\app\SystemServiceRegistry.java->getSystemService();
/** * Gets a system service from a given context. */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; } ... ... private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>();
那这个SYSTEM_SERVICE_FETCHERS又是存的什么呢?整个类中我们只找到了一个用put的方法:
/** * Statically registers a system service with the context. * This method must be called during static initialization only. */ private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); }
这里存的是ServiceFetcher类型
static abstract interface ServiceFetcher<T> { T getService(ContextImpl ctx); }
registerService看名字似乎是注册服务的时候用的,还是个私有的类,我们再往下找找,可以发现在SystemServiceRegistry.java的静态代码块注册了这些系统服务:
static { registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() { @Override public AccessibilityManager createService(ContextImpl ctx) { return AccessibilityManager.getInstance(ctx); }}); registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class, new CachedServiceFetcher<CaptioningManager>() { @Override public CaptioningManager createService(ContextImpl ctx) { return new CaptioningManager(ctx); }}); registerService(Context.ACCOUNT_SERVICE, AccountManager.class, new CachedServiceFetcher<AccountManager>() { @Override public AccountManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.ACCOUNT_SERVICE); IAccountManager service = IAccountManager.Stub.asInterface(b); return new AccountManager(ctx, service); }}); ... ... }
可以看到存入的值都是CachedServiceFetcher类型,CachedServiceFetcher类继承createService。
/** * Override this class when the system service constructor needs a * ContextImpl and should be cached and retained by that context. */ static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> { private final int mCacheIndex; public CachedServiceFetcher() { mCacheIndex = sServiceCacheSize++; } @Override @SuppressWarnings("unchecked") public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; synchronized (cache) { // Fetch or create the service. Object service = cache[mCacheIndex]; if (service == null) { service = createService(ctx); cache[mCacheIndex] = service; } return (T)service; } } public abstract T createService(ContextImpl ctx); }
可以看到createService是在当前ServiceFetcher的 getService里执行的。
哦,明白了,当获取到的服务是在另一个进程时,比如上面的AccountManager.class;先通过ServiceManager获取到了该服务的BP段,然后通过IAccountManager.Stub.asInterface(b);通过Binder驱动找到该服务的Bn端,然后将Bn端保存起来。这样getSystemService()得到的是该服务的Bn端,就可以跨进程通信了。(这里涉及到了Binder跨进程通信和AIDL)
*注:当Android系统第一次开机启动时,会开始注册系统服务,并把这些服务和ServiceManager进行关联
相关文章推荐
- Android的 getSystemService
- Android之getSystemService 各种系统服务总结
- Android----getSystemService
- [转载]android中getSystemService详解
- android中的系统级服务getSystemService(name)
- Android 关于getSystemService()方法的一些常用服务
- Service---android中getSystemService详解
- Android中getSystemService详解
- android中getSystemService详解
- Android getSystemService()调用
- Android之getSystemService
- Android getSystemService()
- android中LayoutInflater的3种使用以及getSystemService的API
- getSystemService() in Android
- Android getSystemService
- Android之getSystemService()方法
- android中LayoutInflater的3种使用以及getSystemService的API
- Androidの系统服务之getSystemService
- Android的getSystemService(String)
- tm=(TelephonyManager)getSystemService(TELEPHONY_SERVICE); cr=Sample5_16_Activity.this.getContentResolver(); bCheck=(Button)this.findV