优点:java
与Linux中的Pipe管道、信号Signal、消息队列Message、共享内存Share Memory、Socket插口等相比较,Binder在进程间传输数据,只须要执行一次拷贝操做。所以它不只提升了效率,并且节省了内存空间。android
角色:web
交互过程:dom
1.Server进程,先经过ServiceManager注册服务,其实是写入Binder驱动和保存到serviceInfo(已经注册的服务列表)。ide
2.Client进程在访问Server服务以前,先经过ServiceManager查询获取到它的一个BinderProxyd对象,而后经过这个Binder代理接口向它发送进程间通信请求,调用transact(),写入相关信息。svg
3.在server进程中,每一个服务都对应一个Binder对象,它经过一个stub来等待Client进程发来进程间通信请求,触发onTransact(),获取到详细数据。函数
Binder机制分析以下:
this
1. ServiceManager类的代理,实现注册和查询服务:代理
接下来查看,如何建立一个SericeManager的代理类,客户端经过该代理类进行通信:指针
查看ServiceManager源码:
public final class ServiceManager { private static IServiceManager sServiceManager; private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // 获取到代理对象 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } }
查看,BinderInternal类
public class BinderInternal { //从native获取到对应的指针 public static final native IBinder getContextObject(); }
查看,ServiceManagerNative源码:
public abstract class ServiceManagerNative extends Binder implements IServiceManager{ /** * Cast a Binder object into a service manager interface, generating * a proxy if needed. */ static public IServiceManager asInterface(IBinder obj){ if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ServiceManagerProxy(obj); } public IBinder asBinder(){ return this; } } class ServiceManagerProxy implements IServiceManager { private IBinder mRemote; public ServiceManagerProxy(IBinder remote) { mRemote = remote; } public IBinder asBinder() { return mRemote; } //......省略部分源码 }
ServiceManagerNative相似服务端的stub类,用于接受到Client端发来的数据,进行操做。
ServiceManagerProxy是客户端的proxy类,经过BinderProxy对象(即mRemote对象)进行远程通信。
Server进程经过ServiceManager进行addService()
注册服务或者Client进程经过ServiceManager进行getService(String name)
查询服务等操做,实际上都是经过ServiceManagerProxy中的mRemote跨进程操做的。
这里不介绍Binder驱动,涉及 C++层比较繁琐,相关方面,自行百度理解。
编写一个aidl文件:
package com.xingen.remoteservice; import com.xingen.remoteservice.bean.ProcessBean; // Declare any non-default types here with import statements //使用 Android Studio,增量编译几乎会当即生成 Binder 类 //在.aidl文件中定义一些方法 interface CommonAidlInterface { /** * 获取一个随机数的字符串 */ String getRandomNumberStr(); /** * 获取远程服务返回的对象,注意点:须要import导入该对象 */ ProcessBean getRemoteServiceObject(); }
生成对应的java:
package com.xingen.remoteservice; // Declare any non-default types here with import statements //使用 Android Studio,增量编译几乎会当即生成 Binder 类 //在.aidl文件中定义一些方法 public interface CommonAidlInterface extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements CommonAidlInterface { private static final String DESCRIPTOR = "com.xingen.remoteservice.CommonAidlInterface"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.xingen.remoteservice.CommonAidlInterface interface, * generating a proxy if needed. */ public static CommonAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof CommonAidlInterface))) { return ((CommonAidlInterface)iin); } return new 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_getRandomNumberStr: { data.enforceInterface(DESCRIPTOR); String _result = this.getRandomNumberStr(); reply.writeNoException(); reply.writeString(_result); return true; } case TRANSACTION_getRemoteServiceObject: { data.enforceInterface(DESCRIPTOR); com.xingen.remoteservice.bean.ProcessBean _result = this.getRemoteServiceObject(); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements CommonAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public String getInterfaceDescriptor() { return DESCRIPTOR; } @Override public String getRandomNumberStr() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); String _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getRandomNumberStr, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; } /** * 获取远程服务返回的对象,注意点:须要import导入该对象 */ @Override public com.xingen.remoteservice.bean.ProcessBean getRemoteServiceObject() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); com.xingen.remoteservice.bean.ProcessBean _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getRemoteServiceObject, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = com.xingen.remoteservice.bean.ProcessBean.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; } } static final int TRANSACTION_getRandomNumberStr = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_getRemoteServiceObject = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public String getRandomNumberStr() throws android.os.RemoteException; /** * 获取远程服务返回的对象,注意点:须要import导入该对象 */ public com.xingen.remoteservice.bean.ProcessBean getRemoteServiceObject() throws android.os.RemoteException; }
CommonAidlInterface接口:
CommonAidlInterface接口是IInteface的子接口,用于Stub类和Proxy的通用父类接口。
Stub类:
Stub类是Binder的子类,用于Server进程中,onTransact()
方法中接收传递过来的信息。
Proxy类:
Proxy中有一个IBinder类型的mRemote对象,它其实是一个BinderProxy对象(经过ServiceManager)。BinderProxy是一个Java服务代理对象,实现了IBinder接口。
2. Client端的Proxy代理(实际包含BinderProxy对象)信息传递:
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //Stub.asInterface(service)转成对应的服务接口 remoteServiceInterface = CommonAidlInterface.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { remoteServiceInterface = null; } };
绑定Service会返回一个IBinder对象,其实是BinderProxy类,该对象是查询ServiceManager获取到的。
public static CommonAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } //本地进程会走这一步 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof CommonAidlInterface))) { return ((CommonAidlInterface)iin); } //远程进程会返回Proxy return new Proxy(obj); } private static class Proxy implements CommonAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } }
Stub.asInterface(iBinder)
是将BinderProxy对象封装到一个代理Proxy中,用于更好操做。
跨进程间的传递信息的调用:
remoteServiceInterface.getRemoteServiceObject();
实际上调用的是Proxy中的getRemoteServiceObject():
@Override public com.xingen.remoteservice.bean.ProcessBean getRemoteServiceObject() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); com.xingen.remoteservice.bean.ProcessBean _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getRemoteServiceObject, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = com.xingen.remoteservice.bean.ProcessBean.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; }
会调用BinderProxy的transact()方法,传入数据和结果的parcel对象,会写入Binder驱动中。
3. Server端的Stub(Binder子类)接受到远程的信息:
Binder驱动监听到Client端远程信息,会触发Binder中的onTransact()方法。
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) case TRANSACTION_getRandomNumberStr: { data.enforceInterface(DESCRIPTOR); //调用该方法 String _result = this.getRandomNumberStr(); reply.writeNoException(); //写入返回结果 reply.writeString(_result); return true; } case TRANSACTION_getRemoteServiceObject: { data.enforceInterface(DESCRIPTOR); com.xingen.remoteservice.bean.ProcessBean _result = this.getRemoteServiceObject(); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } } return super.onTransact(code, data, reply, flags); }
最后,响应到service中的Stub匿名内部类中,调用各类对应的方法。
public class CommonRemoteService extends Service { @Override public IBinder onBind(Intent intent) { Log.i(TAG,TAG+" 被绑定"); return mBinder; } /** * 获取进程信息的对应实体 * @return */ private ProcessBean getProcessBean(){ return ProcessUtils.getProcess(this.getApplicationContext(),ProcessUtils.getCurrentProcessId()); } /** * 获取一个随机字符串 * @return */ private String getRandomUUIDStr(){ return UUID.randomUUID().toString(); } /** * 建立一个CommonAidlInterface.aidl对应的CommonAidlInterface.java中的Stub接口 * * 用于与远程服务通信,这里是本类(CommonRemoteService)通信 */ private final CommonAidlInterface.Stub mBinder=new CommonAidlInterface.Stub() { @Override public String getRandomNumberStr() throws RemoteException { return CommonRemoteService.this.getRandomUUIDStr(); } @Override public ProcessBean getRemoteServiceObject() throws RemoteException { return CommonRemoteService.this.getProcessBean(); } }; }