Android FrameWork 学习

1.Android Binder 学习(一) 系统服务的Bin

2023-08-08  本文已影响0人  Tsm_2020

Binder 是什么? 作者的个人理解

1.对于系统来说,Binder 类似于血管,链接这ServiceMananger ActivityManagerService ActivityTaskManagerService,承载着他们之间的信息的传递
2.对于kernel 底层来说,binder 是驱动,是一种虚拟的底层驱动
3.对于Java 应用层来说,他是一个封装了一套序列化的 Clint 与 Service 信息交互类

想要了解Binder 就不得不从AIDL 说起, AIDL 为我们封装了一套标准的 Clint 与 Service 端的交互方式,我们如何来使用它交互呢,先看一下 简单的AIDL 的编译后的类的结构

我们来看一下为什么说AIDL是一套 Clint/Service 交互方式呢

image.png

简单的创建了一个AIDL 的 interface
使用这个文件编译后的 文件目录大体是下面这个样子

public interface IMyAidlInterface extends android.os.IInterface
{
/** Default implementation for IMyAidlInterface. */
public static class Default implements com.example.myservice.IMyAidlInterface
{
  @Override public void say() throws android.os.RemoteException
  {
  }
  @Override public java.lang.String getStringContent() throws android.os.RemoteException
  {
    return null;
  }
  @Override
  public android.os.IBinder asBinder() {
    return null;
  }
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.myservice.IMyAidlInterface
{
  public Stub()
  {
    this.attachInterface(this, DESCRIPTOR);
  }

  public static com.example.myservice.IMyAidlInterface asInterface(android.os.IBinder obj)
  {
    if ((obj==null)) {
      return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin!=null)&&(iin instanceof com.example.myservice.IMyAidlInterface))) {
      return ((com.example.myservice.IMyAidlInterface)iin);
    }
    return new com.example.myservice.IMyAidlInterface.Stub.Proxy(obj);
  }
  @Override public android.os.IBinder asBinder()
  {
    return this;
  }
  private static class Proxy implements com.example.myservice.IMyAidlInterface
  {
    private android.os.IBinder mRemote;
    Proxy(android.os.IBinder remote)
    {
      mRemote = remote;
    }
    @Override public android.os.IBinder asBinder()
    {
      return mRemote;
    }
    public java.lang.String getInterfaceDescriptor()
    {
      return DESCRIPTOR;
    }
    public static com.example.myservice.IMyAidlInterface sDefaultImpl;
  }
  public static com.example.myservice.IMyAidlInterface getDefaultImpl() {
    return Stub.Proxy.sDefaultImpl;
  }
}

}
image.png

现在思考一个问题,为什么Clint 拿道的是一个Proxy ,Service 交出的是一个Stub 呢,他们两个为什么不能拿到同一个对象吗,那样使用起来多方便,这个里面就存在一个问题,由于进程是隔离,这就让他们同时持有一个对象变得不可能,此时就有另外一个说法,能不能为两个APP 进程开辟同一个系统的内核空间呢,这样两面只要操作内核空间就可以了,其实这种方案也有一个弊端,那就是一端在写的同时,另一端来读数据,这就造成了数据混乱或者就是脏数据,最后就形成了现在的Binder 的这种使用代理的通信机制,

通过代码来看一下他们的依赖关系是什么

Clint 端

我们在BinderService 的过程中都会传入一个ServiceConncetion 对象,在bind成功后会调用 AIDLInterface.Stub.asInterface 来获取 AIDL Interface.Stub.Proxy 的示例


  private ServiceConnection serviceConnection=new ServiceConnection() {
      @Override
      public void onServiceConnected(ComponentName name, IBinder service) {
          IMyAidlInterface binder = IMyAidlInterface.Stub.asInterface(service);
      }
      @Override
      public void onServiceDisconnected(ComponentName name) {
      }
  };

在Interface.Stub 中做了一下判断,传进来是是否是IInterface,不是就创建一个Proxy

  public static com.example.myservice.IMyAidlInterface asInterface(android.os.IBinder obj)
  {
    if ((obj==null)) {
      return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin!=null)&&(iin instanceof com.example.myservice.IMyAidlInterface))) {
      return ((com.example.myservice.IMyAidlInterface)iin);
    }
    return new com.example.myservice.IMyAidlInterface.Stub.Proxy(obj);
  }

上面就是Clint 端建立链接的过程

Service 端

public class MyService extends Service  {

  private final IMyAidlInterface.Stub binder=new IMyAidlInterface.Stub() {
      @Override
      public void say() throws RemoteException {
      }

      @Override
      public String getStringContent() throws RemoteException {
          return "Hellow";
      }
  };
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
      return binder;
  }
}

service 端在内部创建了一个IInterface 的Stub ,在onBind的时候将这个 stub 对外提供,来做数据通信

整个过程看起来很简单,那么对于Android 系统来说,SystemServer 是如何来调度和管理各个 IInterface 的呢,我们就以ActivityTaskManagerService一个为例

App 启动过程

App启动的过程是通过zygote fork 出来的,具体的过程就是调用 ZygoteIntent.forkSystemService 方法复制出来的,具体的代码如下

     pid = Zygote.forkSystemServer(
                  parsedArgs.mUid, parsedArgs.mGid,
                  parsedArgs.mGids,
                  parsedArgs.mRuntimeFlags,
                  null,
                  parsedArgs.mPermittedCapabilities,
                  parsedArgs.mEffectiveCapabilities);

fork 出app进程后,启动流程就在SystemServer中了,在SystemServer 的Run 方法内 做了3个特别重要的方法

   startBootstrapServices(t);
          startCoreServices(t);
          startOtherServices(t);

其中 startBootstrapServices 这个方法中就初始化了 ActivityTaskManagerService,我们来看一下代码

      // Activity manager runs the show.
      t.traceBegin("StartActivityManager");
      // TODO: Might need to move after migration to WM.
      ActivityTaskManagerService atm = mSystemServiceManager.startService(
              ActivityTaskManagerService.Lifecycle.class).getService(); //启动atms
      mActivityManagerService = ActivityManagerService.Lifecycle.startService(
              mSystemServiceManager, atm); // 启动AMS
      mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
      mActivityManagerService.setInstaller(installer);
      mWindowManagerGlobalLock = atm.getGlobalLock();
      t.traceEnd();

可以看到启动的是 mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class),我们继续来看SystemServiceManager 的startService

public <T extends SystemService> T startService(Class<T> serviceClass) {
      try {
          final String name = serviceClass.getName();
          Slog.i(TAG, "Starting " + name);
          Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

          // Create the service.
          if (!SystemService.class.isAssignableFrom(serviceClass)) {
              throw new RuntimeException("Failed to create " + name
                      + ": service must extend " + SystemService.class.getName());
          }
          final T service;
          try {
              Constructor<T> constructor = serviceClass.getConstructor(Context.class);
              service = constructor.newInstance(mContext);
          } catch (InstantiationException ex) {
              throw new RuntimeException("Failed to create service " + name
                      + ": service could not be instantiated", ex);
          } catch (IllegalAccessException ex) {
              throw new RuntimeException("Failed to create service " + name
                      + ": service must have a public constructor with a Context argument", ex);
          } catch (NoSuchMethodException ex) {
              throw new RuntimeException("Failed to create service " + name
                      + ": service must have a public constructor with a Context argument", ex);
          } catch (InvocationTargetException ex) {
              throw new RuntimeException("Failed to create service " + name
                      + ": service constructor threw an exception", ex);
          }

          startService(service);
          return service;  
      } finally {
          Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
      }
  }



  public void startService(@NonNull final SystemService service) {
      // Register it.
      mServices.add(service);
      // Start it.
      long time = SystemClock.elapsedRealtime();
      try {
          service.onStart();
      } catch (RuntimeException ex) {
          throw new RuntimeException("Failed to start service " + service.getClass().getName()
                  + ": onStart threw an exception", ex);
      }
      warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
  }

SystemServiceManager 通过类对象使用反射创建一个实例,在将这个service实例添加到 mService 这个SystemService 的list 当中,并执行ActivityTaskManagerService.Lifecycle的onStart 方法
ActivityTaskManagerService.Lifecycle 继承自SystemService

  public static final class Lifecycle extends SystemService {
      private final ActivityTaskManagerService mService;

      public Lifecycle(Context context) {
          super(context);
          mService = new ActivityTaskManagerService(context);
      }

      @Override
      public void onStart() {
          publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
          mService.start();
      }

      @Override
      public void onUserUnlocked(@NonNull TargetUser user) {
          synchronized (mService.getGlobalLock()) {
              mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier());
          }
      }

      @Override
      public void onUserStopped(@NonNull TargetUser user) {
          synchronized (mService.getGlobalLock()) {
              mService.mTaskSupervisor.mLaunchParamsPersister
                      .onCleanupUser(user.getUserIdentifier());
          }
      }

      public ActivityTaskManagerService getService() {
          return mService;
      }
  }

在 ActivityTaskManagerService.Lifecycle 的onstart 方法中,将一个在ActivityTaskManagerService.Lifecycle 初始化过程中创建ActivityTaskManagerService 的mService 放入到了SystemService publishBinderService,

我们先来看一下 ActivityTaskManagerService 这个类的继承关系

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}

可以看到他就是一个aidl 中的一个服务端的Stub 代理类,我们继续向下看 SystemServcie 的publishBinderService方法

  protected final void publishBinderService(@NonNull String name, @NonNull IBinder service) {
      publishBinderService(name, service, false);
  }

  /**
   * Publish the service so it is accessible to other services and apps.
   *
   * @param name the name of the new service
   * @param service the service object
   * @param allowIsolated set to true to allow isolated sandboxed processes
   * to access this service
   */
  protected final void publishBinderService(@NonNull String name, @NonNull IBinder service,
          boolean allowIsolated) {
      publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
  }
  protected final void publishBinderService(String name, IBinder service,
          boolean allowIsolated, int dumpPriority) {
      ServiceManager.addService(name, service, allowIsolated, dumpPriority);
  }

在这个方法里面将这个 service 放入到了ServiceManager 中,继续向下看


  private static IServiceManager getIServiceManager() {
      if (sServiceManager != null) {
          return sServiceManager;
      }

      // Find the service manager
      sServiceManager = ServiceManagerNative
              .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
      return sServiceManager;//ServiceManagerProxy
  }

  public static void addService(String name, IBinder service, boolean allowIsolated,
          int dumpPriority) {
      try {
          getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
      } catch (RemoteException e) {
          Log.e(TAG, "error in addService", e);
      }
  }

这个里面就是获取到了一个 IServiceManager 的 IInterface Stub 的实例,继续往下看就是c++相关的文件了,这里我贴一下IServiceManager 当中定义 serviceManager 的相关代码
这段代码在IServiceManager.cpp 文件中

using AidlServiceManager = android::os::IServiceManager;

上面所有的代码流程其实就是想说明一下,在activity 当中通过getSystemService 获取的 各类manager 都是 Binder 机制中的 Stub,我们可以通过Stub 进行跨进程通信 ,再来梳理一遍 IInterface 注册Stub 的整个过程

1.ZygoteInit fork app 进程 , 启动SystemServer.main()方法,在SystemServer main 方法中创建了一个 SystemServer,并执行SystemServer 的run 方法

2.SystemServer run方法中执行了3个比较重要的方法,其中startBootstrapServices 中 通过 SystemServiceManager 使用反射启动了 ActivityTaskManagerService.Lifecycle ,启动后将他放入到mservice 这个list 中,并执行service.onstart方法

3.ActivityTaskManagerService.Lifecycle 的onstart 方法中将 ActivityTaskManagerService.Lifecycle 初始化过程中创建的 ActivityTaskManagerService 放入publishBinderService 方法中, ActivityTaskManagerService 就是一个IInterface.Stub 的实例

4.SystemService 将 这个 Stub 放入到 ServiceManager 中

5.由ServiceManager 做了Native 的桥梁管理这些 IInterface.Stub ,

整个过程就是下面这种图这样的


image.png

本来这篇想写一下ActivityManagerService 的启动过程的,但是发现 ActivityManagerService 没有将这个IInterface.Stub 的实例放入到ServiceManager 当中,看来应该是没有对外调度的方法,或者不想让开发者参与进来,
根据ServiceManager 这个管理者我们可以理解为,ServiceManager 是通过binder 来进行跨进程的任务调度,他管理这所有进程的一些服务,

了解了Binder 的 基本通信逻辑,接下来我们继续分析一下bindService 这个过程中到底使用了几次跨进程通信

上一篇下一篇

猜你喜欢

热点阅读