Binder机制

Binder概念
1 机制 Binder是一种Android中实现跨进程通信(IPC)的方式
2 从组成,设备来说,什么是Binder Binder还是一种虚拟的物理设备驱动 /dev/binder
3 从Android代码来说 BInder 是一个类,实现了IBinder接口

可以这么理解AIDL和Binder的关系:
AIDL:是定义的一种通信规范
BInder:是一种具体的通信媒介

跨进程通信方式实现:
服务端
第一步:
创建一个服务Service,返回一个IBinder对象

public class MyService extends Service {
    @Override
    public void onCreate() {super.onCreate();}
    /**
     * 提供给客户端
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //MyApp myApp;
        return new MyAppIml();
    }
}

第二步:创建一个AIDL文件
aild文件其实是一个模板类,系统会根据这个模板自动生成别的java代码

//接口里只能定义基本的数据类型
interface MyApp {
    String getName();
    String setName(String name);
}

第三步:build工程,系统会自动生成一些java代码

客户端
1.将服务端提供的AIDL文件和aild所在的包,拷贝到客户端工程
2.build编译

  1. 在需要和服务端通信的地方调用bindService ,重写ServiceConnection对象的onServiceConnected方法,参数中的ibinder即为服务端传递过来的IBinder对象,这样便可以完成跨进程间的通信。
public void load(View view) {
        Intent intent = new Intent();
        intent.setAction("com.example.baby.binderframwork.MyService");
        intent.setPackage("com.example.baby.binderframwork");
        //进程B 目的   binderServise  ----->  IBinder iBinder
        // c.conn.connected(r.name, service);
        bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                    //proxy   装煤炭  Proxy 对象  MyApp接口
               MyApp myApp= MyApp.Stub.asInterface(iBinder);
                try {
                    myApp.setName("xxx");
                    Toast.makeText(MainActivity.this, "--->  " + myApp.getName(), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        }, Context.BIND_AUTO_CREATE);
    }

查看通过aild文件生成的对应的java文件发现该接口继承android.os.IInterface

public interface MyApp extends android.os.IInterface {
    /**
     * Stub表示接收方
     */
    public static abstract class Stub extends android.os.Binder implements com.example.baby.binderframwork.MyApp {
        private static final java.lang.String DESCRIPTOR = "com.example.baby.binderframwork.MyApp";

        /**
         * DESCRIPTOR相当于一个进程的id或tag
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        public static com.example.baby.binderframwork.MyApp asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
  //根据DESCRIPTOR查询是否在同一个进程
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.example.baby.binderframwork.MyApp))) {
                return ((com.example.baby.binderframwork.MyApp) iin);
            }
//不在同一个进程则返回Proxy对象(Proxy implement MyApp)
            return new com.example.baby.binderframwork.MyApp.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_getName: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _result = this.getName();
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
                case TRANSACTION_setName: {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    java.lang.String _result = this.setName(_arg0);
                    reply.writeNoException();
                    reply.writeString(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

//Proxy表示发送方
        private static class Proxy implements com.example.baby.binderframwork.MyApp {
            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 java.lang.String getName() throws android.os.RemoteException {
//Parcel写入另一个进程的参数,类似于一个缓存区,用来保存传递的数据(要访问的类)
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.lang.String _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    
//调用另一个进程即Binder进程 会调用Binder中的onTransact方法
//  TRANSACTION_getName参数为调用哪个方法(int类型)
mRemote.transact(Stub.TRANSACTION_getName, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

            @Override
            public java.lang.String setName(java.lang.String name) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.lang.String _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeString(name);
                    mRemote.transact(Stub.TRANSACTION_setName, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_getName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_setName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }

    public java.lang.String getName() throws android.os.RemoteException;

    public java.lang.String setName(java.lang.String name) throws android.os.RemoteException;
}

我们再来看下Binder的transact方法
Binder.java

 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;
    }

客户端给服务端发送消息:


image.png

再来看下客户端绑定服务(bindService())时的经过:

bindService()方法的真正实现类为ContextImpl,看源码

ContextWrapper.java

@Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return 
//mBase为Context 
//bindService 真的实现为ContextImpl
mBase.bindService(service, conn, flags);
    }

ContextImpl.java

@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;
        .......
//ActivityManagerNative.getDefault()的类型为IActivityManager
//IActivityManager extends IInterface 类似于AIDL接口
//ActivityManagerNative extends Binder implements IActivityManager 类似于Stub
//ActivityManagerProxy implements IActivityManager 类似于Proxy
//class ActivityManagerService extends ActivityManagerNative

//调用ActivityManagerProxy的bindService
            int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
           .....
    }

ActivityManagerProxy.java
ActivityManagerProxy implements IActivityManager 类似于Proxy

public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType, IServiceConnection connection,
            int flags,  String callingPackage, int userId) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeStrongBinder(token);
        service.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(connection.asBinder());
        data.writeInt(flags);
        data.writeString(callingPackage);
        data.writeInt(userId);
//调用另一个进程即Binder进程 会调用Binder中的onTransact方法
        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
        reply.readException();
        int res = reply.readInt();
        data.recycle();
        reply.recycle();
        return res;
    }

ActivityManagerNative.java
ActivityManagerNative extends Binder implements IActivityManager 类似于Stub

 @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
.....

        case BIND_SERVICE_TRANSACTION: {
            ...
//调用ActivityManagerService的bindService
            int res = bindService(app, token, service, resolvedType, conn, fl,
                    callingPackage, userId);
            ...
            return true;

}

ActivityManagerService.java
ActivityManagerService extends ActivityManagerNative
ActivityManagerNative extends Binder implements IActivityManager 类似于Stub

public int bindService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
        .....

        synchronized(this) {
//调用ActiveServices的bindServiceLocked
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }

ActiveServices.java

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags,
            String callingPackage, int userId) throws TransactionTooLargeException {
....
 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);

...//检查调用者是否存在....

            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//创建ConnectionRecord 
            ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent);

//得到IBinder对象,就是要回调给客户端的IBinder对象
//并添加到集合保存
            IBinder binder = connection.asBinder();
            ArrayList clist = s.connections.get(binder);
            if (clist == null) {
                clist = new ArrayList();
                s.connections.put(binder, clist);
            }
            clist.add(c);
            b.connections.add(c);
            if (activity != null) {
                if (activity.connections == null) {
                    activity.connections = new HashSet();
                }
                activity.connections.add(c);
            }
            b.client.connections.add(c);
            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
                b.client.hasAboveClient = true;
            }
            if (s.app != null) {
                updateServiceClientActivitiesLocked(s.app, c, true);
            }
            clist = mServiceConnections.get(binder);
            if (clist == null) {
                clist = new ArrayList();
                mServiceConnections.put(binder, clist);
            }
            clist.add(c);

            ...进行四种情况判断...
//1.整个进程B没有启动()
//2.进程有了但Service没有创建(执行ActivityThread的scheduleCreateService)
//3.进程有了Service创建了但没有被客户端绑定(执行ActivityThread的scheduleBindService)
//4.进程有了Service创建了已经被其他客户端绑定 (执行onRebind)
...
}

ActivityThread.java

public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            ...
//发送给Hander
            sendMessage(H.CREATE_SERVICE, s);
        }

public final void scheduleBindService(IBinder token, Intent intent,
                boolean rebind, int processState) {
            .....
//发送给Hander
            sendMessage(H.BIND_SERVICE, s);
        }

H.java extends Handler

private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
//重要的地方,可以替换为我们的DexClassLoader干别的
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
//反射的方式创建Service
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
//调用Service生命周期中的attach方法
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
//调用Service生命周期中的onCreate方法
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

    private void handleBindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        if (DEBUG_SERVICE)
            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                try {
                    if (!data.rebind) {
//重点 调用service的onBind方法返回IBinder对象
                        IBinder binder = s.onBind(data.intent);
//发送给客户端          
ActivityManagerNative.getDefault().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManagerNative.getDefault().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ensureJitEnabled();
                } catch (RemoteException ex) {
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(s, e)) {
                    throw new RuntimeException(
                            "Unable to bind to service " + s
                            + " with " + data.intent + ": " + e.toString(), e);
                }
            }
        }
    }

Binder核心机制


Binder核心机制.png

你可能感兴趣的:(Binder机制)