AIDL跨进程通信

来源:互联网 发布:电纸书阅读器软件 编辑:程序博客网 时间:2024/04/24 03:21

Binder是android中进程通信的信使,是客户端和服务端通信的媒介,当bindService的时候,服务端会返回一个binder对象,然后客户端就可以根据binder操作服务端的数据。普通服务和aidl都是这么完成的。今天就来详细探讨下aidl的使用。
使用aidl首先是要定义一个aid接口,然后系统会为我们生成用的代码,里面就包含我们的媒介binder,还有几个特殊的方法:

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

先来定义一个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简单的三部曲就完成了。

了解更多,可以关注公众号

这里写图片描述

原创粉丝点击