AIDL中使用Interface接口回调
16lz
2021-01-26
在AIDL——Android接口定义语言初步探索中实现了客户端主动调用服务端的方法获取数据,如果服务端的方法是异步执行的,等待结果出来后再通知客户端或者需要服务端主动给客户端传递信息,这个时候就需要使用接口回调了。
这里只实现服务器端主动把数据传递给所有连接的客户端,需求就是当服务端数据增加时,把最新的数据通过接口回调传递给客户端。异步执行需要的接口回调类似。
在AIDL——Android接口定义语言初步探索代码基础上修改,不明白的可以先看看这篇
- 定义接口文件
在aidl目录的包中新建一个aidl文件,声明一个方法
// IMyAidlInterface.aidlpackage com.aidl.server;// Declare any non-default types here with import statementsimport com.aidl.server.InfoBean;//引入定义的aidl文件,使用序列化对象,interface IMyAidlInterface { void onCallbackAllInfo(in List books);}
- 添加注册和注销监听的方法
在InfoManager.aidl文件中添加两个方法:
void registerListener(IMyAidlInterface listener);//注册监听 void unregisterListener(IMyAidlInterface listener);//销毁监听
- 在服务端实现注册和销毁监听的方法,并实现需求
定义一个对象管理所有客户端注册的监听对象
private RemoteCallbackList mListListener=new RemoteCallbackList();
RemoteCallbackList是系统专门提供的用于删除跨进程listener的接口,它是一个泛型,支持管理任意的AIDL接口。遍历RemoteCallbackList必须按照指定的方式,通过beginBroadcast方法获得元素个数,通过getBroadcastItem(int position)获得元素对象,遍历结束后调用finishBroadcast()方法。
遍历一个RemoteCallbackList对象
final int N=mListListener.beginBroadcast(); for(int i=0;iif(I!=null){ //TODO } } mListListener.finishBroadcast();
把listener添加到RemoteCallbackList:
mListListener.register(listener);
注销listener:
mListListener.unregister(listener);
服务器端实现注册和注销listener:
@Override public void registerListener(IMyAidlInterface listener) throws RemoteException { if(listener!=null){ mListListener.register(listener); final int N=mListListener.beginBroadcast(); Log.e("registerListener", "size:"+N); mListListener.finishBroadcast(); } } @Override public void unregisterListener(IMyAidlInterface listener) throws RemoteException { if(listener!=null){ mListListener.unregister(listener); final int N=mListListener.beginBroadcast(); Log.e("unregisterListener", "size:"+N); mListListener.finishBroadcast(); } }
通过打印RemoteCallbackList元素的个数确定是否注册成功和注销成功。
服务端实现需求(当服务端数据更新时,给所有连接的客户端发送信息):
@Override public void addInfo(InfoBean info) throws RemoteException { if(Infos==null){ Infos=new ArrayList(); } if(info==null)return; Infos.add(info); Log.e("ServerAdd",Infos.toString()); //当服务端数据有更新时,通过接口回调通知所有连接的客户端,并把最新的数据传递给客户端 final int N=mListListener.beginBroadcast(); for(int i=0;iif(I!=null){ I.onCallbackAllInfo(Infos); } } mListListener.finishBroadcast(); }
- 客户端实现
首先,定义一个IMyAidlInterface对象:
private IMyAidlInterface iMyAidlInterface=new IMyAidlInterface.Stub() { @Override public void onCallbackAllInfo(List books) throws RemoteException { Log.e("Client1",books.toString()); } };
在连接服务器成功后注册listener:
Log.e("Client1","Server连接成功"); mInfoManager= InfoManager.Stub.asInterface(service); isServerStart=true; try { mInfoManager.registerListener(iMyAidlInterface); } catch (RemoteException e) { e.printStackTrace(); }
在activity生命周期onDestroy中注销listener:
@Override protected void onDestroy() { super.onDestroy(); if(isServerStart){ try { mInfoManager.unregisterListener(iMyAidlInterface); } catch (RemoteException e) { e.printStackTrace(); } unbindService(mServiceConnection); } }
运行程序,看一下打印结果
client1点击发送时
client2点击发送时
服务端打印结果
更多相关文章
- Android(安卓)小型社交软件客户端开发技术栈+案例
- kotlin优雅实现AIDL
- Android怎样绕开Camera打开手电筒的LED
- 第三部分:Android(安卓)应用程序接口指南---第三节:应用程序资源--
- 几个开源XMPP Android客户端简单比较
- 见证Android消息推送时刻(源码及详解)
- Android(安卓)APP开发文档模板
- Tomcat双向Https验证搭建,亲自实现与主流浏览器、Android/iOS移动
- Android(安卓)MVP模式 入门