返回 登录
10

AIDL 客户端与服务端的双向通信

时隔一年半了,终于写下了这个续篇,我发现我的很多博客有头无尾,都是有前面一点点,后面就没写去了,也正在想办法都补上

初涉IPC,了解AIDL的工作原理及使用方法
今天聊聊的是客户端和服务端的相互通信,何谓双向通信,事实上,我们在上一篇的博客中,只是讲解了客户端请求服务端的方法,然后服务端返回一个值给我们这样,其实是最简单的用法,但是常常在我们的开发过程中,如果调用了某些方法,比如网络请求,那么就需要等待请求有结果了之后再回调给我们,这个回调的过程就是服务端向客户端通信,作为ipc通信的一种,如果你不会双向通信,那么你可以比较low的用广播,但是我还是建议你直接用一整套的AIDL复用,好的,那么问题来了,我们怎么下手呢?

服务端

我们新建两个工程,一个叫ADILClient,一个叫AIDLService,分别代表的是客户端和服务端

我们现在开始编写我们的aidl,这里我需要编写两个AIDL文件,一个是我们对外的方法,一个是我们对外的回调方法,如图

这里我做一下讲解,首先我new了一个aidl的文件夹,在main下,和java同级,然后定义了一个公共的包名:com.android.openimpl,最后在里面实现了两个aidl文件,我们来看下具体的文件内容

IMyLifeStyleInterface

// IMyLifeStyleInterface.aidl
package com.android.openimpl;

import com.android.openimpl.IMyLifeStyleListener;

interface IMyLifeStyleInterface {

//计算
void sum(int a ,int b);
//睡觉
void sleep(boolean isSleep);

//注册
void registerCallback(IMyLifeStyleListener il);
//解绑
void unregisterCallback(IMyLifeStyleListener il);

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IMyLifeStyleListener

// IMyLifeStyleListener.aidl
package com.android.openimpl;

//回调接口
interface IMyLifeStyleListener {

//回调方法
void OnCallBackSleep(String text);
void OnCallBackSize(int size);
}
1
2
3
4
5
6
7
8
9
10
11
这里我定义了IMyLifeStyleInterface ,里面有两个方法,假设我定义的事一个人,他有基本的两个本能,一个是计算,我传两个数字给他,他进行一系列的处理,那么,问题来, 我不想用返回值,我想通过回调知道,这是一点,另一个是睡觉,而在IMyLifeStyleListener,我也定义了两个对应的回调OnCallBackSleep和OnCallBackSize,好了,现在开始来实现我们的远程Service服务

public class OpenImplService extends Service {

private IMyLifeStyleListener lifeStyleListener;

private IBinder mBinder = new IMyLifeStyleInterface.Stub() {
    @Override
    public void sum(int a, int b) throws RemoteException {
        //经过一系列的计算后将值告知客户端
        int c = a * 2 + b;
        if (lifeStyleListener != null) {
            lifeStyleListener.OnCallBackSize(c);
        }
    }

    @Override
    public void sleep(boolean isSleep) throws RemoteException {
        //告诉客户端我已经睡着
        if(isSleep){
            if (lifeStyleListener != null) {
                lifeStyleListener.OnCallBackSleep("帮我关下灯,谢谢!");
            }
        }
    }

    @Override
    public void registerCallback(IMyLifeStyleListener il) throws RemoteException {
        if (il != null) {
            lifeStyleListener = il;
        }
    }

    @Override
    public void unregisterCallback(IMyLifeStyleListener il) throws RemoteException {
        if (il != null) {
            lifeStyleListener = null;
        }
    }
};

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
这里,我定义了一个远程的服务OpenImplService,里面我只是new了IMyLifeStyleInterface.Stub并且把Binder对象给了onBind方法,而在Binder内部,我做的操作相信大家都看的明白吧,很简单,Ok,那我们的服务端就已经搞定了,我们来看下服务端的整体结构

当然,别忘了在清单文件中注册

   <service
        android:name=".service.OpenImplService"
        android:enabled="true"
        android:exported="true" />

1
2
3
4
客户端

好的,现在就开始来实现我们的客户端,客户端也需要同样的AIDL文件,所以我可以直接复制过去,但是要注意的是包名一定要相同,如图

这里,我的客户端就是app包下的东西,那么我们来实现UI上的逻辑

评论