首页 > 程序开发 > 移动开发 > 其他 >

AIDL跨进程通信

2017-09-05

AIDL跨进程通信。Binder是android中进程通信的信使,是客户端和服务端通信的媒介,当bindService的时候,服务端会返回一个binder对象,然后客户端就可以根据binder操作服务端的数据。普通服务和aidl都是这么完成的。今天就来详细探讨下aidl的使用。

Binder是android中进程通信的信使,是客户端和服务端通信的媒介,当bindService的时候,服务端会返回一个binder对象,然后客户端就可以根据binder操作服务端的数据。普通服务和aidl都是这么完成的。今天就来详细探讨下aidl的使用。

使用aidl首先是要定义一个aid接口,然后系统会为我们生成用的代码,里面就包含我们的媒介binder,还有几个特殊的方法:

asInterface(android.os.IBinder obj)这个方法是将服务端传过来的binder对象转换成aidl类型的接口,便于我们去操作服务端数据。 asbinder,由名字就知道返回当前的binder对象。 自己定义的方法。

先来定义一个aidl文件

interface IMaidl {

    String getName();

}

一个最简单的aidl代码,看看系统自动生成了什么样的代码

public interface IMaidl extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements com.example.apple.db.IMaidl {
        private static final java.lang.String DESCRIPTOR = "com.example.apple.db.IMaidl";

        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an com.example.apple.db.IMaidl interface,
         * generating a proxy if needed.
         */
        public static com.example.apple.db.IMaidl asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.example.apple.db.IMaidl))) {
                return ((com.example.apple.db.IMaidl) iin);
            }
            return new com.example.apple.db.IMaidl.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;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements com.example.apple.db.IMaidl {
            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 {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                java.lang.String _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_getName, _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);
    }

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

我们上面提到的方法都有吧。下面看看服务端的代码

public class AIDLService extends Service {


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    IMaidl.Stub binder = new IMaidl.Stub() {
        @Override
        public String getName() throws RemoteException {
            return getServiceName();
        }


    };

    String getServiceName() {
        return "这是服务端给的信息";
    }


}

绑定服务,别忘了还需要到xml注册服务。

        bindService(new Intent(this, AIDLService.class), new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
              IMaidl  iMaidl = IMaidl.Stub.asInterface(service);

             String name1 = iMaidl.getName();
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        }, BIND_AUTO_CREATE);

通过aidl定义的接口,跨进程调用服务端的数据 String name1 = iMaidl.getName();。
aidl简单的三部曲就完成了。

相关文章
最新文章
热点推荐