Binder通信机制
1.什么是Binder
Binder 是一种进程间通信机制,基于开源的 OpenBinder 实现;OpenBinder 起初由 Be Inc. 开发,后由 Plam Inc. 接手。从字面上来解释 Binder 有胶水、粘合剂的意思,顾名思义就是粘和不同的进程,使之实现通信。
2.什么时候需要用到进程间通信?
Android开发者们都知道,Android 应用程序是由 Activity、Service、Broadcast Receiver 和 Content Provide 四大组件中的一个或者多个组成的。然而有时这些组件运行在同一进程,有时运行在不同的进程。这些进程间的通信就依赖于 Binder IPC 机制。Android 系统对应用层提供的各种服务如:ActivityManagerService、PackageManagerService 等都是基于 Binder IPC 机制来实现的。还有就是支付宝纳入海量应用、大型登入架构的实现等等。由此可见Binder 机制在 Android 中的位置非常重要。
3.进程间通信为什么要用到Binder机制?
Android 系统是基于 Linux 内核的,Linux 已经提供了共享内存和 Socket 等 IPC 机制。那为什么 Android 还要提供 Binder 来实现 IPC 呢?
Binder通信与其他通信的区别如下图:
4. 进程间通信原理
在Android系统中每一个进程的用户空间(User Space)都是隔离的,进程1没有办法直接访问进程2的数据,这也就是所谓的进程隔离,但是内核空间(Kernal Space)是共享的。当进程1发起系统调用时(Binder实现IPC通信),进行一个复制数据到内核空间的缓存区,再通过mmap的映射关系,就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。(整个过程就是一个数据copy和一个内存数据映射过程)
4.Biner通信机制的简单实现(AIDL)
通常我们在开发时,实现进程间通信的最多可能就是AIDL了,当我在AS中定义好我们的.AIDL文件,AS就会给我们直接生成对应的实现IPC通信的.java文件,因此帮助我们进一步了解IPC通信机制。
AIDL实现进程通信时序图IBinder : IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
IInterface : IInterface 代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)
Binder : Java 层的 Binder 类,代表的其实就是 Binder 本地对象。BinderProxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。
Stub : AIDL 的时候,编译工具会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要开发者自己实现。
4.1.AS自动生成的代码
package com.drsports;/** * @author Vson * 项目描述:这个是客户端AIDL自动生成的,里面有注释过程 */public interface IMyAidlInterface extends android.os.IInterface { ... /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements IMyAidlInterface { //描述符 private static final java.lang.String DESCRIPTOR = "IMyAidlInterface"; /** * Construct the stub at attach it to the interface. */ public Stub() { //挂载接口 this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an IMyAidlInterface interface, * generating a proxy if needed. * *将一个IBinder对象转换成com.drsports.server.IMyAidlInterface接口, * *如果需要,生成代理。(动态代理) */ public static IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof IMyAidlInterface))) { //查看是否本地接口,如果是本地接口,直接返回 return ((IMyAidlInterface) iin); } //如果不是本地接口,远程获取一个接口(句柄) return new IMyAidlInterface.Stub.Proxy(obj); } ... @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { //这个是远程的Server,因为客户端和服务端的代码是一个的,为了节省空间就是贴出来 java.lang.String descriptor = DESCRIPTOR; switch (code) { ... case TRANSACTION_addPerson: { ... //调用继承类的addPerson(_arg0)方法,也就是 //AidlService中的new IMyAidlInterface.Stub() this.addPerson(_arg0); reply.writeNoException(); return true; } .... } } private static class Proxy implements IMyAidlInterface { //内部对象 public static IMyAidlInterface sDefaultImpl; //发送数据(远程IBinder) private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { //获取远程IBinder return mRemote; } public java.lang.String getInterfaceDescriptor() { //获取描述符 return DESCRIPTOR; } @Override public void addPerson(com.drsports.server.Person person) throws android.os.RemoteException { //客户端发送数据 android.os.Parcel _data = android.os.Parcel.obtain(); //服务端返回数据 android.os.Parcel _reply = android.os.Parcel.obtain(); try { //C层校验数据 _data.writeInterfaceToken(DESCRIPTOR); if ((person != null)) { _data.writeInt(1); person.writeToParcel(_data, 0); } else { _data.writeInt(0); } //调用服务端方法,将客服端挂起,直到服务端返回数据 //flags 是0表示客户端和服务端相互通信;是1表示客户端只能发送,服务端不能返回数据 //Stub.TRANSACTION_addPerson方法ID boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { getDefaultImpl().addPerson(person); return; } //读取异常 _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } ..... } static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_getPersonList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);...
4.2.客户调用代码
/** * onAIDLServer点击事件 * * @param view */ public void onAIDLServer(View view) { try { //使用服务句柄调用服务方法,完成IPC通行 myAidlInterface.addPerson(new Person("vson", 2)); List mList = myAidlInterface.getPersonList(); Log.d("sss", mList.toString()); } catch (RemoteException e) { e.printStackTrace(); } } private IMyAidlInterface myAidlInterface; private ServiceConnection connection2 = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //获取服务句柄 myAidlInterface = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { myAidlInterface = null; } }; //进入页面时调用完成bind代码 public void myBindService() { Intent intent = new Intent(); //服务端通过反射创建的Service remoteServer = new ComponentName("com.drsports.server", "com.drsports.server.AidlService"); intent.setComponent(remoteServer); bindService(intent, connection2, Service.BIND_AUTO_CREATE); }
4.3.服务端代码
package com.drsports.server;/** * @author vson */public class AidlService extends Service { private ArrayList mList; @Nullable @Override public IBinder onBind(Intent intent) { mList = new ArrayList<>(); return binder; } private IBinder binder = new IMyAidlInterface.Stub() { @Override public void addPerson(Person person) throws RemoteException { Log.d("TAG", person.toString()); mList.add(person); } @Override public List getPersonList() throws RemoteException { return mList; } };}
当客户端调用bindService时,系统层代码会调用connection2中的onServiceConnected实现一次服务绑定,而在onServiceConnected中,通过IMyAidlInterface.Stub.asInterface(service)获取服务端的server句柄,这个过程是动态代理的过程。接下来当客户端调用 myAidlInterface.addPerson(new Person("vson", 2)),是调用实现IMyAidlInterface接口的Proxy中的addPerson方法,其中 mRemote.transact()方法就是内核层使用Binder调用远程Server的onTransact()方法。在Server端中的AIDL中有一个this.addPerson()方法其实是调用Stub的实现类的addPerson方法,也就是上面服务端代码new IMyAidlInterface.Stub() 的addPerson()方法。
5.Biner通信机制的源码分析(API23中bindService实现)
当客户端调用bindServer方法时,进入了Context的装饰类ContextWrapper中,但是真正实现bindServer方法的是Context的实现类ContextImpl:
public class ContextWrapper extends Context {... @Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { return mBase.bindService(service, conn, flags); }...}
class ContextImpl extends Context {... @Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, Process.myUserHandle()); } private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) { IServiceConnection sd;... if (mPackageInfo != null) { //ServiceConnection的接口回调的封装 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), mMainThread.getHandler(), flags); } ... // ActivityManagerNative.getDefault() 返回就相当于AIDL的proxy //而这个Proxy就是ActivityManagerService类 int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier());...}
//ActivityManagerNative==>Stubpublic abstract class ActivityManagerNative extends Binder implements IActivityManager{ /** * Cast a Binder object into an activity manager interface, generating * a proxy if needed. */ static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); } /** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { //返回Binder 的proxy return gDefault.get(); } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case BIND_SERVICE_TRANSACTION: { ... IServiceConnection conn = IServiceConnection.Stub.asInterface(b); //调用真正的服务(启动服务)ActivityManagerService int res = bindService(app, token, service, resolvedType, conn, fl, callingPackage, userId); ... }} private static final Singleton gDefault = new Singleton(){ protected IActivityManager create() { //IBiner就是AMS服务,这个是系统启动时添加进去的 IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } //获取远程服务句柄 IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };}//ActivityManagerProxy ===>proxyclass ActivityManagerProxy implements IActivityManager{... public ActivityManagerProxy(IBinder remote) { mRemote = remote; } public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws RemoteException { .... //进行远程调用服务方法 mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0); ... }...}
public interface IActivityManager extends IInterface {}
有上面的代码可以看出:bindServer过程是调用ContextImpl的bindSever方法进而调用了bindServiceCommon方法,bindServiceCommon方法中调用了ActivityManagerNative.getDefault().bindService方法,可以看出ActivityManagerNative.getDefault()返回的IActivityManager就相当与AIDL中实现 IMyAidlInterface的Proxy,而这个Proxy就是ActivityManagerService类;而ActivityManagerNative.getDefault().bindService()就是相当于Proxy.bindService();IActivityManager继承IInterface接口,所以IActivityManager就相当于AIDL接口IMyAidlInterface ;可以看出ActivityManagerNative和ActivityManagerProxy就是相当于Stub和Proxy的关系。
整理如下图:
接下来我在看ActivityManagerService这个类:
public final class ActivityManagerService extends ActivityManagerNative{... public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("bindService"); .... synchronized(this) { //同步处理(枷锁) //mServices是ActiveServices return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } }...}
public final class ActiveServices { int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { ... if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); //>1.进程B,整个进程都没有启动 //>2.进程B启动了,但是里面的Service没有创建出来 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) { return 0; } } ... if (b.intent.apps.size() == 1 && b.intent.doRebind) { //重新bind服务 //1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind() //2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind() requestServiceBindingLocked(s, b.intent, callerFg, true); } else if (!b.intent.requested) { //没有bind服务 //1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind() //2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind() requestServiceBindingLocked(s, b.intent, callerFg, false); } } private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) throws TransactionTooLargeException { ... final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; ProcessRecord app; if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); if (app != null && app.thread != null) { //>1.进程B,整个进程都没有启动 //>2.进程B启动了,但是里面的Service没有创建出来 //B进程已成启动了 try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); realStartServiceLocked(r, app, execInFg); return null; } } } ... return null; }} private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... //ProcessRecord是一个进程记录,ProcessRecord.thread指向的是ActivityThread.ApplicationThread app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true; ... }
public final class ActivityThread {... public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false); CreateServiceData s = new CreateServiceData(); s.token = token; s.info = info; s.compatInfo = compatInfo; //这里是Handler消息 sendMessage(H.CREATE_SERVICE, s); } public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) { updateProcessState(processState, false); BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; s.rebind = rebind; //这里是Handler消息 sendMessage(H.BIND_SERVICE, s); } public void handleMessage(Message msg) {... case CREATE_SERVICE: handleCreateService((CreateServiceData)msg.obj); break;..} //真正创建服务的方法 private void handleCreateService(CreateServiceData data){ //使用类加载器加载Service java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); .... ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false, mInstrumentation); //服务挂载参数 service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); //服务的生命周期onCreate方法回调 service.onCreate(); //存储服务,如果再次创建就从这个获取 mServices.put(data.token, service); ... }...}
A进程访问B进程时几种状态
1.bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null)
1.进程B,整个进程都没有启动
2.进程B启动了,但是里面的Service没有创建出来
2.requestServiceBindingLocked(s, b.intent, callerFg, false);
1.进程B启动了,里面的Service也创建了,但是Service没有绑定过,回调onBind()
2.进程B启动了,里面的Service也创建了,但是Service已经绑定过,回调onRebind()
更多相关文章
- Android(安卓)ionic工程中调用webrtc获取视频流
- Android中Activity组件的生命周期
- Android知识点(自己版)
- Android(安卓)NDK之JNI陷阱
- Android网络访问的基本方法
- Android中保存和恢复Fragment状态的最好方法
- Android文件存储--采用SharedPreferences保存用户偏好设置参数和
- android之service简单介绍
- 几个比较混淆概念,android中的Info类以及PackageManager和Activit