Android进程通信之aidl

2017-07-22  本文已影响0人  HunterGao35

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

上一篇下一篇

猜你喜欢

热点阅读