从AIDL开始谈Android进程间Binder通信机制(4)

一方面连接成功时调用了serviceConnection的onServiceConnected方法。我们从该方法中获取到一个Binder对象(注意,这个binder并不是我们在service中实现的那个哦。当service时本apk中的service时,这里返回的是同一个binder),我们通过此binder来与server进行通信。为了区分,我们称为clientBinder。

public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG,"connect");
            binded=true;
            mCalculateAIDL= ICalculateAIDL.Stub.asInterface(service);     
}

另一方面,onBind方法返回了我们实现的Stub对象,其实也是一个Binder,用于和Client进行通信。(之前我们定义了一个aidl接口文件,并根据它生成了ICalculateAIDL接口。这个接口中有我们定义的两个方法以及一个静态抽象内部类Stub,它是一个Binder的子类。)我们来看一下Stub是如何定义的:

public static abstract class Stub extends android.os.Binder implements com.cqumonk.calculate.aidl.ICalculateAIDL

它继承了Binder类也实现了ICalculateAIDL接口,我们实现了定义的add和minus方法。我们仍然要强调一下它并不是clientBinder,在负责与clientBinder进行通信交互的同时,它也维护了service描述符与服务端service的映射。

我们在Client中的onServiceConnected里调用了stub对象的asInterface方法,并将之前得到的clientBinder传入:

public static com.cqumonk.calculate.aidl.ICalculateAIDL asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);//根据包名获取本地实现的一个接口的实例,如果是本地service则可以获取到
            if (((iin != null) && (iin instanceof com.cqumonk.calculate.aidl.ICalculateAIDL))) {
                return ((com.cqumonk.calculate.aidl.ICalculateAIDL) iin);  //如果得到的实例是ICalculateAIDL的对象,则返回
            }
            return new com.cqumonk.calculate.aidl.ICalculateAIDL.Stub.Proxy(obj);//如果无法得到本地实现的对象则会返回一个代理对象
}

在这个方法中,首先在系统中查找注册的的service,如果没有找到,那么一定是别的apk实现的service,于是返回一个此service的静态代理类对象供Client调用。我们来看一下这个代理,创建时我们将clientBinder传入了,同时也它实现了ICalculateAIDL接口:

private static class Proxy implements com.cqumonk.calculate.aidl.ICalculateAIDL {
            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 int add(int a, int b) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(a);  //将参数打包
                    _data.writeInt(b);
                    mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);  //调用binderDriver的提供的方法将参数发给服务端
                    _reply.readException();
                    _result = _reply.readInt();  //读取到返回结果
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/7b8815e0e112fef9faf7181875de0c35.html