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通信与其他通信的区别如下图:

Binder与传统IPC通信对比

4. 进程间通信原理

在Android系统中每一个进程的用户空间(User Space)都是隔离的,进程1没有办法直接访问进程2的数据,这也就是所谓的进程隔离,但是内核空间(Kernal Space)是共享的。当进程1发起系统调用时(Binder实现IPC通信),进行一个复制数据到内核空间的缓存区,再通过mmap的映射关系,就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。(整个过程就是一个数据copy和一个内存数据映射过程)

Binder IPC原理

4.Biner通信机制的简单实现(AIDL)

通常我们在开发时,实现进程间通信的最多可能就是AIDL了,当我在AS中定义好我们的.AIDL文件,AS就会给我们直接生成对应的实现IPC通信的.java文件,因此帮助我们进一步了解IPC通信机制。

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 的相关实现需要开发者自己实现。

AIDL实现进程通信时序图

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的关系。

整理如下图:

image.png
接下来我在看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()

更多相关文章

  1. Android(安卓)ionic工程中调用webrtc获取视频流
  2. Android中Activity组件的生命周期
  3. Android知识点(自己版)
  4. Android(安卓)NDK之JNI陷阱
  5. Android网络访问的基本方法
  6. Android中保存和恢复Fragment状态的最好方法
  7. Android文件存储--采用SharedPreferences保存用户偏好设置参数和
  8. android之service简单介绍
  9. 几个比较混淆概念,android中的Info类以及PackageManager和Activit

随机推荐

  1. Android selector 状态选择器
  2. Android 模拟J2me 通过连接框架
  3. 创建你的第一个Android PHP应用
  4. [转]Android基础类库
  5. Android之进程与线程
  6. android使用socket使底层和framework通信
  7. android源码/内核下载
  8. android静默安装的实现(一)
  9. Android项目中集成React Native
  10. android 4.0 编译模式 eng -- > user 时