Android 使用AIDL实现进程之间的通信(一)

来源:互联网 发布:中国数据分析行业网 编辑:程序博客网 时间:2024/06/06 02:11

下面开始介绍下Android 之间进程之间的通信方式,AIDL是Android之间进程通信的方式之一,底层依然使用的是Binder,随后会介绍Binder的实现原理

创建AIDL文件

在AndroidStudio 中创建AIDL文件,会自动创建AIDL目录,在工程中与Java目录平级

// IMyAidl.aidlpackage cn.edu.hebust.aidldemo;// Declare any non-default types here with import statementsinterface IMyAidl {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     * AIDL 通信的基本数据类型     */    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);    // 提供给其他客户端的接口方法    int add(int num1, int num2);}

ctrl+b 进行编译,或者是用SDKtool提供的工具,将AIDL文件编译成.java文件
生成的java文件在
~/app/build/generated/source/aidl/debug/cn/edu/hebust/aidldemo

这个文件不需要我们更改,但是理解以后对我们了解Binder还是很有帮助的

/* * This file is auto-generated.  DO NOT MODIFY. * Original file: /media/yangtianrui/system/AndroidProject/AndroidStudioProjects/AIDLDemo/app/src/main/aidl/cn/edu/hebust/aidldemo/IMyAidl.aidl */package cn.edu.hebust.aidldemo;// Declare any non-default types here with import statementspublic interface IMyAidl extends android.os.IInterface {    /**     * Local-side IPC implementation stub class.     */    public static abstract class Stub extends android.os.Binder implements cn.edu.hebust.aidldemo.IMyAidl {        private static final java.lang.String DESCRIPTOR = "cn.edu.hebust.aidldemo.IMyAidl";        /**         * Construct the stub at attach it to the interface.         */        public Stub() {            this.attachInterface(this, DESCRIPTOR);        }        /**         * Cast an IBinder object into an cn.edu.hebust.aidldemo.IMyAidl interface,         * generating a proxy if needed.         */        public static cn.edu.hebust.aidldemo.IMyAidl asInterface(android.os.IBinder obj) {            if ((obj == null)) {                return null;            }            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);            if (((iin != null) && (iin instanceof cn.edu.hebust.aidldemo.IMyAidl))) {                return ((cn.edu.hebust.aidldemo.IMyAidl) iin);            }            return new cn.edu.hebust.aidldemo.IMyAidl.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_basicTypes: {                    data.enforceInterface(DESCRIPTOR);                    int _arg0;                    _arg0 = data.readInt();                    long _arg1;                    _arg1 = data.readLong();                    boolean _arg2;                    _arg2 = (0 != data.readInt());                    float _arg3;                    _arg3 = data.readFloat();                    double _arg4;                    _arg4 = data.readDouble();                    java.lang.String _arg5;                    _arg5 = data.readString();                    this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);                    reply.writeNoException();                    return true;                }                case TRANSACTION_add: {                    data.enforceInterface(DESCRIPTOR);                    int _arg0;                    _arg0 = data.readInt();                    int _arg1;                    _arg1 = data.readInt();                    int _result = this.add(_arg0, _arg1);                    reply.writeNoException();                    reply.writeInt(_result);                    return true;                }            }            return super.onTransact(code, data, reply, flags);        }        private static class Proxy implements cn.edu.hebust.aidldemo.IMyAidl {            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;            }            /**             * Demonstrates some basic types that you can use as parameters             * and return values in AIDL.             * AIDL 通信的基本数据类型             */            @Override            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException {                android.os.Parcel _data = android.os.Parcel.obtain();                android.os.Parcel _reply = android.os.Parcel.obtain();                try {                    _data.writeInterfaceToken(DESCRIPTOR);                    _data.writeInt(anInt);                    _data.writeLong(aLong);                    _data.writeInt(((aBoolean) ? (1) : (0)));                    _data.writeFloat(aFloat);                    _data.writeDouble(aDouble);                    _data.writeString(aString);                    mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);                    _reply.readException();                } finally {                    _reply.recycle();                    _data.recycle();                }            }            @Override            public int add(int num1, int num2) 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(num1);                    _data.writeInt(num2);                    mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);                    _reply.readException();                    _result = _reply.readInt();                } finally {                    _reply.recycle();                    _data.recycle();                }                return _result;            }        }        static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);        static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);    }    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     * AIDL 通信的基本数据类型     */    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;    public int add(int num1, int num2) throws android.os.RemoteException;}

提供对外开放的Service

public class MyServer extends Service {    // 这里是对提供的Java AIDL文件的实现    // 通过onBind方法对外通信    private IMyAidl.Stub mStub = new IMyAidl.Stub() {        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        // 我们需要调用的方法        @Override        public int add(int num1, int num2) throws RemoteException {            return num1 + num2;        }    };    @Nullable    @Override    public IBinder onBind(Intent intent) {        return mStub;    }}

这个Service的声明如下,我们需要这个Service对外开放,并且使用单独的进程运行

<!--process 带有':'属性表示这个组件的进程是私有的,只要有有互端去启动,系统就会创建一个新的进程去运行--><!--不带表示这个进程时共享的&ndash;&gt;--><service    android:name=".MyServer"    android:exported="true"    android:process=":remote">    <intent-filter>        <action android:name="cn.hebust.myservice" />    </intent-filter></service>

客户端的AIDL

这里客户端要拿到服务端的AIDL目录,并且实现对应的Java文件

// 直接在MainActivity中进行进行bindServicepublic class MainActivity extends AppCompatActivity {    private IMyAidl mStub;    // 使用一个Connection实现相互通信    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            mStub = IMyAidl.Stub.asInterface(service);            try {                // 调用aidl interface的方法                int value = mStub.add(5, 5);                Toast.makeText(MainActivity.this, value + "", Toast.LENGTH_SHORT).show();            } catch (RemoteException e) {                e.printStackTrace();            }        }        @Override        public void onServiceDisconnected(ComponentName name) {        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 启动服务端程序        Intent intent = new Intent();        intent.setAction("cn.hebust.myservice");        ComponentName componentName = new ComponentName("cn.edu.hebust.aidldemo"                , "cn.edu.hebust.aidldemo.MyServer");        intent.setComponent(componentName);        bindService(intent, conn, Context.BIND_AUTO_CREATE);    }    @Override    protected void onDestroy() {        unbindService(conn);        super.onDestroy();    }}
0 0
原创粉丝点击