Binder机制

2020-01-07  本文已影响0人  patient烽

Binder

Binder传输数据.png 1.png

AIDL使用

定义一个AIDL文件,IPersonAidl.aidl,系统会编译生成IPersonAidl.java

interface ILeoAidl {
  void addPerson(in Person person);

  List<Person> getPersonList();
}
//获取aidl对象的方法
private ServiceConnection connection = new ServiceConnection() {
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
    //IPersonAidl为定义IPersonAidl.aidl文件自动生成的java文件
    iPersonAidl = IPersonAidl.Stub.asInterface(service);
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
    iPersonAidl = null;
  }
};

客户端:

分析生成的IPersonAidl.java中Proxy的方法,用来发送数据给服务端

private static class Proxy implements com.xx.leo_service.ILeoAidl {
    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;
    }

    @Override
    public void addPerson(com.xx.leo_service.Person person) throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            if ((person != null)) {
                _data.writeInt(1);
                person.writeToParcel(_data, 0);
            } else {
                _data.writeInt(0);
            }
            mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public java.util.List<com.xx.leo_service.Person> getPersonList() throws android.os.RemoteException {
      //发送到服务端的数据 
        android.os.Parcel _data = android.os.Parcel.obtain();
     // 服务端返回的数据
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.util.List<com.xx.leo_service.Person> _result;
        try {
          //校验是否是当前服务
            _data.writeInterfaceToken(DESCRIPTOR);
          //然后服务端就会调用onTransact()
            mRemote.transact(Stub.TRANSACTION_getPersonList, _data, _reply, 0);
            _reply.readException();
            _result = _reply.createTypedArrayList(com.xx.leo_service.Person.CREATOR);
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }
}

Binder#transact

public class Binder{
  /**
 * Default implementation rewinds the parcels and calls onTransact.  On
 * the remote side, transact calls into the binder to do the IPC.
 */
    public final boolean transact(int code, Parcel data, Parcel reply,
        int flags) throws RemoteException {
    if (false) Log.v("Binder", "Transact: " + code + " to " + this);
    if (data != null) {
        data.setDataPosition(0);
    }
    //会调用onTransact()
    boolean r = onTransact(code, data, reply, flags);
    if (reply != null) {
        reply.setDataPosition(0);
    }
    return r;
    }
}

服务端:

public class PersonService extends Service {
  public IBinder onBind(Intent intent) {
    persons = new ArrayList<>();
    Log.e("LeoPersonServiceService", "success onBind");
    return iBinder;
  }
  private IBinder iBinder = new IPersonAidl.Stub() {
    @Override
    public void addPerson(Person person) throws RemoteException {
      persons.add(person);
    }

    @Override
    public List<Person> getPersonList() throws RemoteException {
      return persons;
    }
  };
}
public static abstract class Stub extends android.os.Binder implements com.xx.leo_service.IPersonAidl {
    private static final java.lang.String DESCRIPTOR = "com.xx.leo_service.IPersonAidl";

    /**
     * 服务端Service中new Stub的时候会设置一个DESCRIPTOR
     */
    public Stub() {
        this.attachInterface(this, DESCRIPTOR);
    }

    public static com.xx.leo_service.ILeoAidl asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
      //先去查询DESCRIPTOR是否设置,如果是客户端,服务端在同一个进程,DESCRIPTOR是有值的,就能直接拿到这个服务端实例,而不需要通过Proxy,也就是通过binder去中转数据
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.xx.leo_service.IPersonAidl))) {
            return ((com.xx.leo_service.IPersonAidl) iin);
        }
        return new com.xx.leo_service.IPersonAidl.Stub.Proxy(obj);
    }  

    @Override
    public android.os.IBinder asBinder() {
        return this;
    }

    @Override
    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply,
                              int flags) throws android.os.RemoteException {
        switch (code) {
            case INTERFACE_TRANSACTION: {
                reply.writeString(DESCRIPTOR);
                return true;
            }
            case TRANSACTION_addPerson: {
                data.enforceInterface(DESCRIPTOR);
                com.xx.leo_service.Person _arg0;
                if ((0 != data.readInt())) {
                    _arg0 = com.xx.leo_service.Person.CREATOR.createFromParcel(data);
                } else {
                    _arg0 = null;
                }
                this.addPerson(_arg0);
                reply.writeNoException();
                return true;
            }
            case TRANSACTION_getPersonList: {
                data.enforceInterface(DESCRIPTOR);
                java.util.List<com.xx.leo_service.Person> _result = this.getPersonList();
                reply.writeNoException();
                reply.writeTypedList(_result);
                return true;
            }
        }
        return super.onTransact(code, data, reply, flags);
    }

那我们的客户端是如何与服务端进行通讯的呢,首先我们需要先绑定服务端Service

public class MainActivity extends Activity{
  private void bindService() {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.xx.leo_service", "com.xx.leo_service.AidlService"));
    bindService(intent, connection, Context.BIND_AUTO_CREATE);
  }
}

ContextImpl#bindService

private class ContextImpl extend Context{
  public boolean bindService( Intent service, int flags, Executor executor, ServiceConnection conn) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
  }

  private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, String instanceName, Handler handler, Executor executor, UserHandle user) {
    //...
    //ActivityManager.getService()返回远程服务的代理对象:IActivityManager
    int res =ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(), getActivityToken(), service,service.resolveTypeIfNeeded(getContentResolver()),sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
  }
}

ActivityManager#getService()

public class ActivityManager{
  private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
    @Override
    protected IActivityManager create() {
      // b是服务端返回的IBinder对象
      final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
      //能看出IActivityManager是一个aidl类,am就是上面例子中的aidl对象中的Proxy:客户端,
      final IActivityManager am = IActivityManager.Stub.asInterface(b);
      return am;
    }
  };
  public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
  }
}

那上面的ServiceManager.getService(Context.ACTIVITY_SERVICE)获取到的是什么对象呢?其实就是ActivityManagerService,会在ActivityManagerService#setSystemProcess方法中添加进来

ActivityManagerService#setSystemProcess

//继承自IActivityManager.Stub,说明ActivityManagerService是服务端的实现类
public class ActivityManagerService extends IActivityManager.Stub{
  public void setSystemProcess() {
    //将ActivityManagerService添加到ServiceManager中
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_HIGH);
        ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
        ServiceManager.addService("dbinfo", new DbBinder(this));
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(this),
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
        }
        ServiceManager.addService("permission", new PermissionController(this));
        ServiceManager.addService("processinfo", new ProcessInfoService(this));
    }
}

ActivityManager#getService()返回的类型是 IActivityManager 类型,拿到远程服务的Binder 对象,其中IActivityManager.Stub.asInterface(b)就是拿到远程服务的代理对象:IActivityManager,通过代理对象调用远程的方法,是应用进程与服务进程通信的媒介,IActivityManager#bindIsolatedService最终会调用到ActivityManagerService#bindIsolatedService

ActivityManagerService#bindIsolatedService

public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String instanceName,
        String callingPackage, int userId) throws TransactionTooLargeException {
    //...省略
    synchronized(this) {
        return mServices.bindServiceLocked(caller, token, service,
                resolvedType, connection, flags, instanceName, callingPackage, userId);
    }
}

ActivityServices#bindServiceLocked

public class ActivityServices{
  int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
                        String resolvedType, final IServiceConnection connection, int flags,
                        String callingPackage, final int userId) {
    //...省略
    ConnectionRecord c = new ConnectionRecord(b, activity,
                                              connection, flags, clientLabel, clientIntent,
                                              callerApp.uid, callerApp.processName, callingPackage);
    if ((flags&Context.BIND_AUTO_CREATE) != 0) {
      s.lastActivity = SystemClock.uptimeMillis();
      //注释1:调用bringUpServiceLocked,创建服务,具体看1.1
      if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                               permissionsReviewRequired) != null) {
        return 0;
      }
    }

    if (s.app != null && b.intent.received) {
      // Service is already running, so we can immediately
      // publish the connection.
      try {
        // 具体看2.1 -- c.conn => IServiceConnection.java ,最终会调用到客户端new ServiceConnection的onServiceConnected方法,将服务端的自己创建的IBinder对象传递过去
        //b.intent.binder = 从服务端获取的binder对象
        c.conn.connected(s.name, b.intent.binder, false);
      } 
      //如果已经绑定过了,requestServiceBindingLocked最后一个参数(rebind)为true
      if (b.intent.apps.size() == 1 && b.intent.doRebind) {
        //注释3: -- 具体看3.1 调用requestServiceBindingLocked
        requestServiceBindingLocked(s, b.intent, callerFg, true);
      }
      //如果没有绑定过最后一个参数为false
    } else if (!b.intent.requested) {
      requestServiceBindingLocked(s, b.intent, callerFg, false);
    }
  }

1.1ActivityServices#bringUpServiceLocked

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
                                    boolean whileRestarting, boolean permissionsReviewRequired) {
  //...省略
  ProcessRecord app
  if (!isolated) {
    app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);     
    //app.thread  => ApplicationThread,因为一个进程启动就会走ActivityThread的main方法,会创建ApplicationThread,如果app.thread不为空,说明已经创建了另一个进程,app服务端Service已经启动了,b进程已经启动了,直接绑定服务就行了realStartServiceLocked
    if (app != null && app.thread != null) {
      app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
      //调用realStartServiceLocked,具体看1.2
      realStartServiceLocked(r, app, execInFg);
      return null;
    } 
  }
  //1.3 如果进程B未启动,调用startProcessLocked,启动一个进程,
  if (app == null && !permissionsReviewRequired) {
    if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                                    hostingType, r.name, false, isolated, false)) == null) {
      bringDownServiceLocked(r);
      return msg;
    }
    if (isolated) {
      r.isolatedProc = app;
    }
  }
}

1.2ActivityServices#realStartServiceLocked

private final void realStartServiceLocked(ServiceRecord r,
                                          ProcessRecord app, boolean execInFg){
  //...省略 
  //1.2.1 app.thread = ApplicationThread,调用ApplicationThread的scheduleCreateService方法,创建service
  app.thread.scheduleCreateService(r, r.serviceInfo,
                          mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                                   app.repProcState);
}

1.3ActivityManagerService#startProcessLocked

//开启一个进程
private boolean startProcessLocked(...){
  final String entryPoint = "android.app.ActivityThread";
  startProcess(entryPoint,...);
}

private ProcessStartResult startProcess(){
  final ProcessStartResult startResult;
  if (hostingType.equals("webview_service")) {
    startResult = startWebView(entryPoint,...);
  } else {
    //通过ZygoteProcess启动一个进程 entryPoint = "android.app.ActivityThread"
    startResult = Process.start(entryPoint,..);
  }
}

1.2.1ApplicationThread#scheduleCreateService

public final void scheduleCreateService(IBinder token,
                                        ServiceInfo info, CompatibilityInfo compatInfo, int processState) {    
  CreateServiceData s = new CreateServiceData();
  //发送一个CREATE_SERVICE消息,会在ActivityThread.H中处理
  sendMessage(H.CREATE_SERVICE, s);
}

class H extends Handler {
  public void handleMessage(Message msg) {
    case CREATE_SERVICE:
    //接收到CREATE_SERVICE消息后,创建服务
    handleCreateService((CreateServiceData)msg.obj);
    break;
  }
  private void handleCreateService(CreateServiceData data) {
    LoadedApk packageInfo = getPackageInfoNoCheck(
      data.info.applicationInfo, data.compatInfo);
    Service service = null;
    java.lang.ClassLoader cl = packageInfo.getClassLoader();
    //反射创建service
    service = packageInfo.getAppFactory()
      .instantiateService(cl, data.info.name, data.intent);
    Application app = packageInfo.makeApplication(false, mInstrumentation);
    //调用service的attach(),onCreate()
    service.attach(context, this, data.info.name, data.token, app,
                   ActivityManager.getService());
    service.onCreate();
    mServices.put(data.token, service);      
  }
}

2.1 IServiceConnection#connected

IServiceConnection是一个aidl的类,那么这个实现类是如何创建的呢,回到客户端中ServiceConnection通过bindService传递,会将ServiceConnection转化为IServiceConnection

public class MainActivity extends Activity{
  public void onCreate(){
    //传递自己创建的connection到bindService()中
    bindService(intent, connection, Context.BIND_AUTO_CREATE);
  }
}

ContextImpl#bindServiceCommon

final @NonNull LoadedApk mPackageInfo;
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
                                  handler, UserHandle user) {
  IServiceConnection sd;   
  if (mPackageInfo != null) {
    //sd就是上面2.1步骤用到的c.conn,将自己创建的ServiceConnection通过LoadedApk#getServiceDispatcher(conn)得到,那我们看一下sd的创建过程
    sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
  } else {
    throw new RuntimeException("Not supported in system context");
  }
}

LoadedApk#getServiceDispatcher()

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
                                                     Context context, Handler handler, int flags) {
  LoadedApk.ServiceDispatcher sd = null;
  if (sd == null) {
    //创建ServiceDispatcher,将ServiceConnection当做参数传递
    sd = new ServiceDispatcher(c, context, handler, flags);
  } else {
    sd.validate(context, handler);
  }
  //返回IServiceConnection
  return sd.getIServiceConnection();
}

ServiceDispatcher的类结构,查看IServiceConnection的创建过程,ServiceDispatcherLoadApk的内部类

static final class ServiceDispatcher{
  ServiceDispatcher(ServiceConnection conn,
                    Context context, Handler activityThread, int flags) {
    //IServiceConnection = InnerConnection
    mIServiceConnection = new InnerConnection(this);
    //mConnection = 我们自己创建的ServiceConnection
    mConnection = conn;
  }

  IServiceConnection getIServiceConnection() {
    //返回IServiceConnection,也就是构造方法中创建的InnerConnection,所以上边c.conn.connected,就是调用
    //LoadApk#InnerConnection.connected()
    return mIServiceConnection;
  }
}

InnerConnection#connected

//InnerConnection继承了IServiceConnection.Stub,说明这个InnerConnection相当于服务端实现
private static class InnerConnection extends IServiceConnection.Stub {
  public void connected(ComponentName name, IBinder service, boolean dead){
    LoadedApk.ServiceDispatcher sd = mDispatcher.get();
    if (sd != null) {
      //调用了LoadedApk.ServiceDispatcher#connected
      sd.connected(name, service, dead);
    }
  }
}

LoadedApk.ServiceDispatcher#connected

public void connected(ComponentName name, IBinder service, boolean dead) {
  if (mActivityThread != null) {
    mActivityThread.post(new RunConnection(name, service, 0, dead));
  } else {
    doConnected(name, service, dead);
  }
}

public void doConnected(ComponentName name, IBinder service, boolean dead) {
  ServiceDispatcher.ConnectionInfo old;
  ServiceDispatcher.ConnectionInfo info;

  synchronized (this) {
    if (old != null) {
      old.binder.unlinkToDeath(old.deathMonitor, 0);
    }
  }
  // If there was an old service, it is now disconnected.
  if (old != null) {
    mConnection.onServiceDisconnected(name);
  }
  if (dead) {
    mConnection.onBindingDied(name);
  }
  //mConnection=>构造方法传递的ServiceConnection,所以最终会调用我们自己创建的ServiceConnection的onServiceConnected方法,并将IBinder对象传递
  if (service != null) {
    mConnection.onServiceConnected(name, service);
  } else {
    // The binding machinery worked, but the remote returned null from onBind().
    mConnection.onNullBinding(name);
  }
}

3.1ActivityServices#requestServiceBindingLocked

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
                                                  boolean execInFg, boolean rebind) throws TransactionTooLargeException {
  if (r.app == null || r.app.thread == null) {
    // If service is not currently running, can't yet bind.
    return false;
  }
  if ((!i.requested || rebind) && i.apps.size() > 0) {
    try {
      bumpServiceExecutingLocked(r, execInFg, "bind");
      r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
      //rebind==true,调用Application#scheduleBindService,绑定服务
      r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                                       r.app.repProcState);
      if (!rebind) {
        i.requested = true;
      }
      i.hasBound = true;
      i.doRebind = false;
    } 
  }
  return true;
}

Application#scheduleBindService

public final void scheduleBindService(IBinder token, Intent intent,
                                      boolean rebind, int processState) { 
  BindServiceData s = new BindServiceData();
  //发送一个BIND_SERVICE消息,会在ActivityThread.H处理,会绑定服务
  sendMessage(H.BIND_SERVICE, s);
}

public class ActivityThread{
  public void handleMessage(Message msg) {
    case BIND_SERVICE:
    //接收到BIND_SERVICE消息后,绑定服务
    handleBindService((BindServiceData)msg.obj);            
    break;
  }

  private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);   
    if (s != null) {
      data.intent.setExtrasClassLoader(s.getClassLoader());
      data.intent.prepareToEnterProcess();
      if (!data.rebind) {
        //调用我们自己创建的xxxService的onBind方法,onBind中会返回我们自己创建的 IBinder iBinder = new ILeoAidl.Stub()
        IBinder binder = s.onBind(data.intent);
        //调用ActivityManagerService当中的publishService方法
        ActivityManager.getService().publishService(data.token, data.intent, binder);
      } else {
        s.onRebind(data.intent);
        ActivityManager.getService().serviceDoneExecuting(
          data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
      }
    }
  }

ActivityManagerService#publishService

public void publishService(IBinder token, Intent intent, IBinder service) {
  synchronized(this) {
    //调用ActiveServicecs的publishServiceLocked方法
    mServices.publishServiceLocked((ServiceRecord)token, intent, service);
  }
}

ActiveServicecs#publishServiceLocked

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
  if (r != null) {
    Intent.FilterComparison filter
      = new Intent.FilterComparison(intent);
    IntentBindRecord b = r.bindings.get(filter);
    if (b != null && !b.received) {
      for (int conni=r.connections.size()-1; conni>=0; conni--) {
        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
        for (int i=0; i<clist.size(); i++) {
          ConnectionRecord c = clist.get(i);
          // c.conn => IServiceConnection.java ,上面分析了最终会调用到客户端new ServiceConnection的onServiceConnected方法,将服务端的自己创建的IBinder对象传递过去
          c.conn.connected(r.name, service, false);
        }
      }
    }
    serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
  }
}

最后附上一张时序图


BindService.jpg
上一篇下一篇

猜你喜欢

热点阅读