实现Binder接口的异步通信

利用AIDL实现进程间通信默认是同步的,这样可能会导致阻塞的发生:如果另外一端处于异常状态将导致调用端处于等待状态。
昨天就遇到这样的问题,A、B两个app通过一个公共service通信,A在service中通过AIDL接口调用B中的方法:

for (ISecAppCallback listner : mListener) {
            if (listner != null) {
                Log.i(CLASS_TAG, " start sendStatusToSecApps, tempStatus:" + tempStatus);
                try {
                    listner.EcmStatusCB(tempStatus);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

ISecAppCallback是AIDL接口,ISecAppCallback.aidl中定义了方法:

interface ISecAppCallback {
    void EcmStatusCB(int status);
}

在另一个app中处理EcmStatusCB事件:

private class ISecAPPCallbackImpl extends ISecAppCallback.Stub{

        @Override
        public void EcmStatusCB(int status) throws RemoteException {
            Log.i(getClass().getSimpleName(), "EcmStatusCB called, status:" + status);
            try {
                Log.i(getClass().getSimpleName(), "sleep 5 seconds");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            try {
                Log.i(getClass().getSimpleName(), "sleep 5 seconds");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

默认情况下,A直接调用AIDL通知B,A中打印是这样:
实现Binder接口的异步通信_第1张图片
B中的log:
实现Binder接口的异步通信_第2张图片

两边都是每次调用相隔10秒,时间上是同步的。

下面实现异步调用
在aidl文件中,通过oneway修饰,申明方法为异步:

interface ISecAppCallback {

    //ecm status callback
    oneway void EcmStatusCB(int status);
}

再测试一次,A的log如下:
实现Binder接口的异步通信_第3张图片
没有阻塞,直接调用。
再看看B的log:
实现Binder接口的异步通信_第4张图片
每次调用之间,相隔了10秒,说明两边的通信是异步的。

在aidl文件中,通过oneway修饰,实现了方法的异步调用

你可能感兴趣的:(实现Binder接口的异步通信)