Binder 机制

1、IPC inter-process community   进程间通信

2、bind机制对应的java文件 :Android 理解Binder机制解读AIDL对应的Java文件

3、主要机制是内核空间存在共享区域,基于内存映射mmap来实现ipc通信

 

3、wms、ams、pms系统主要服务都是通过binder机制来实现的

binder transact 和 ontransact 机制 参考:Binder机制详解_nullZgy的博客-CSDN博客

4、ServiceManager getService

ServiceManager是一个独立的进程,其本身也是个service,Framwork提供了个系统方法 BinderInternal.getContextObject(),用来获取SerciceManager对应的Binder应用。该方法返回ServiceManager后,可通过ServiceManager提供的方法,获取其他系统的sercice的Binder引用。这样设计的好处就是系统只需要暴漏一个全局Binder,就可以通过这个全局binder获取其他的系统服务的binder引用,隐藏其他系统服务,从而有助于系统的扩展,以及调用系统服务的安全检查。

系统服务启动时候将自己的binder对象传递给ServiceManager,即所谓的注册(addSercice)。

4、1 ContextImpl.getSystemService()中各种Service的具体获取方式

  @Override
      public Object getSystemService(String name) {
          return SystemServiceRegistry.getSystemService(this, name);
      }
  
      @Override
      public String getSystemServiceName(Class<?> serviceClass) {
          return SystemServiceRegistry.getSystemServiceName(serviceClass);
     }
      /**
       * 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;
      }

ServiceFetcher初始化

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

registerService初始化

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

 4.2 SystemManager.getService()方法的代码如下


public static IBinder gerService(String name){
        try{
              IBinder service =sCashe.get(name);
              if(service != null){
                    return service;
                }else {
                        return getIServiceManager().getService(name);
                }
            }catch(remoteException e){
                Log.e(TAG , "error in getService" , e);
            }
                return null

sCache初始化代码如下 ServiceManager.java

 public static void initServiceCache(Map<String, IBinder> cache) {
          if (sCache.size() != 0) {
              throw new IllegalStateException("setServiceCache may only be called once");
          }
          sCache.putAll(cache);
      }

此函数调用链

1、
SystemServer.main
    SystemService.run
        SystemServer.createSystemContext
            ActivityThread.attach(true)
                AMS.attachApplication
                    AMS.attachApplicationLocked
                        ActivityThread.bindApplication
                            ServiceManager.initServiceCache
 
2、
ActivityThread.main
    ActivityThread.attach(false)
        AMS.attachApplication
            AMS.attachApplicationLocked
                ActivityThread.bindApplication
                    ServiceManager.initServiceCache

传入initServiceCache函数的参数是来自AMS.getCommonServiceLocked。

 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
          if (isolated) {
              if (mIsolatedAppBindArgs == null) {
                  mIsolatedAppBindArgs = new HashMap<>();
                  mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
              }
              return mIsolatedAppBindArgs;
          }
  
          if (mAppBindArgs == null) {
              mAppBindArgs = new HashMap<>();
              mAppBindArgs.put("package", ServiceManager.getService("package"));
              mAppBindArgs.put("window", ServiceManager.getService("window"));
              mAppBindArgs.put(Context.ALARM_SERVICE,
                      ServiceManager.getService(Context.ALARM_SERVICE));
          }
          return mAppBindArgs;
      }

可见,sChache中仅仅包含了package,window、alarm服务

参考 : 启动流程 | SystemService - 简书 (jianshu.com)

ContextImpl.getSystemService - > SystemServiceRegistry.getSystemService -> 
SystemServiceRegistry.fetch.getService < - SystemServiceRegistry.static.registerService <- serviceManager.getService

5、ServiceManager addService注册

systemserver启动系统服务后,会将自身通过servicemanager进行注册,例如AMS:

ActivityManagerService.java

public void setSystemProcess() {
         try {
              ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
       ``````
}

ServiceManager.java 

public static void addService(String name, IBinder service, boolean allowIsolated) {
          try {
              getIServiceManager().addService(name, service, allowIsolated);
          } catch (RemoteException e) {
             Log.e(TAG, "error in addService", e);
          }
      }
ServiceManagerNative.java
public void addService(String name, IBinder service, boolean allowIsolated)
              throws RemoteException {
          Parcel data = Parcel.obtain();
          Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IServiceManager.descriptor);
         data.writeString(name);
         data.writeStrongBinder(service);         
data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }

获取系统服务: getSystemService 

参考:

1、Android中的binder机制详解_大渔歌_的博客-CSDN博客_android binder机制

2、【Service】ServiceManager.getService的流程分析_明朗晨光的博客-CSDN博客_servicemanager.getservice

3、Android跨进程通信:图文详解 Binder机制 原理 - 腾讯云开发者社区-腾讯云 (tencent.com) 

posted @ 2022-12-05 15:36  随易来了  阅读(250)  评论(0编辑  收藏  举报