美文网首页
Android进程通信之aidl

Android进程通信之aidl

作者: HunterGao35 | 来源:发表于2017-07-22 13:14 被阅读0次

    1.aidl使用

    1.aidl文件

    // ICalculator.aidl
    package com.huntergao.demoserver;
    // Declare any non-default types here with import statements
    interface ICalculator {
        int plus(int aInt, int bInt);
        int minus(int aInt, int bInt);
    }
    

    aidl文件添加完毕之后会自动生成ICalculator类, 存放位置

    build/generated/source/aidl/debug/com.huntergao.demoserver.ICalculator.java

    2.服务端

    public class CalculateService extends Service {
    
        private static final String TAG = "CalculateService";
    
        private final Binder binder = new ICalculator.Stub() {
            @Override
            public int plus(int aInt, int bInt) throws RemoteException {
                return aInt + bInt;
            }
    
            @Override
            public int minus(int aInt, int bInt) throws RemoteException {
                return aInt - bInt;
            }
        };
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i(TAG, "onCreate");
        }
        
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            Log.i(TAG, "onBind, intent = " + intent);
            return binder;
        }
    }
    

    服务端主要是实现ICalculator.Stub接口,创建Binder类
    在AndroidManifest.xml注册服务

    <service
        android:name="com.huntergao.demoserver.CalculateService"
        android:exported="true">
        <intent-filter>
             <action android:name="android.intent.action.DEMO_CALCULATE_ACTION" />
        </intent-filter>
    </service>
    

    3.客户端

    客户端也要放入ICalaulator.aidl文件,且包名和服务端的一致,否则会报错误:

    java.lang.SecurityException: Binder invocation to an incorrect interface

    创建ServiceConnection

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i(TAG, "onServiceConnected");
            calculator = ICalculator.Stub.asInterface(iBinder);
            try {
                int sum = calculator.plus(5, 3);
                Log.d(TAG, sum + "");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i(TAG, "onServiceDisconnected, componentName =" + componentName);
        }
    };  
    

    绑定服务

    Intent intent = new Intent();
    intent.setAction("android.intent.action.DEMO_CALCULATE_ACTION");
    // 隐式启动必须设置包名
    intent.setPackage("com.huntergao.demoserver");
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    

    在这里启动,不要使用

    intent.setClassName("com.huntergao.multiscreen", "com.huntergao.demoserver.CalculateService");
    

    解绑服务

    unbindService(serviceConnection);
    

    2.分析AIDL生成的代码

    服务端实现了ICalculator.Stub类

    public static abstract class Stub extends android.os.Binder implements com.huntergao.demoserver.ICalculator {
        // 每一个Binder服务都有一个唯一的标识
        private static final java.lang.String DESCRIPTOR = "com.huntergao.demoserver.ICalculator";
    
        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }
    
        /**
         * Cast an IBinder object into an com.huntergao.demoserver.ICalculator interface,
         * generating a proxy if needed.
         * 该方法由客户端调用,判断binder对象是否处于本进程,处于本进程返回ICalculator对象,否则返回Stub.Proxy对象
         */
        public static com.huntergao.demoserver.ICalculator asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof com.huntergao.demoserver.ICalculator))) {
                return ((com.huntergao.demoserver.ICalculator) iin);
            }
            return new com.huntergao.demoserver.ICalculator.Stub.Proxy(obj);
        }
    
        @Override
        public android.os.IBinder asBinder() {
            return this;
        }
    
        // 当服务端接收到客户端依靠Binder驱动发来的消息时,执行onTransact方法,然后由参数决定执行服务端的代码
        // code 唯一标识,用于区分执行哪个参数,客户端会传递该参数
        // data 客户端传递过来的参数
        // reply 服务端返回的值
       // flag标明是否有返回值,0为有(双向),1为没有(单向)
        @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_plus: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    int _arg1;
                    _arg1 = data.readInt();
                    int _result = this.plus(_arg0, _arg1);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
                case TRANSACTION_minus: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    int _arg1;
                    _arg1 = data.readInt();
                    int _result = this.minus(_arg0, _arg1);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }
    
        private static class Proxy implements com.huntergao.demoserver.ICalculator {
            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 plus(int aInt, int bInt) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;
                try {
                    // 将参数写入data对象,传给服务端
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(aInt);
                    _data.writeInt(bInt);
                    // 调用transact执行服务端代码
                    mRemote.transact(Stub.TRANSACTION_plus, _data, _reply, 0);
                    _reply.readException();
                    // 获取服务端的结果
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
    
            @Override
            public int minus(int aInt, int bInt) 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(aInt);
                    _data.writeInt(bInt);
                    mRemote.transact(Stub.TRANSACTION_minus, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }
    
        static final int TRANSACTION_plus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_minus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }
    

    参考资料

    http://blog.csdn.net/lmj623565791/article/details/38461079

    相关文章

      网友评论

          本文标题:Android进程通信之aidl

          本文链接:https://www.haomeiwen.com/subject/vkajkxtx.html