AIDL中使用Interface接口回调

在AIDL——Android接口定义语言初步探索中实现了客户端主动调用服务端的方法获取数据,如果服务端的方法是异步执行的,等待结果出来后再通知客户端或者需要服务端主动给客户端传递信息,这个时候就需要使用接口回调了。

这里只实现服务器端主动把数据传递给所有连接的客户端,需求就是当服务端数据增加时,把最新的数据通过接口回调传递给客户端。异步执行需要的接口回调类似。

在AIDL——Android接口定义语言初步探索代码基础上修改,不明白的可以先看看这篇

  • 定义接口文件
    在aidl目录的包中新建一个aidl文件,声明一个方法
// IMyAidlInterface.aidl
package com.aidl.server;

// Declare any non-default types here with import statements
import 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点击发送时
这里写图片描述
这里写图片描述

服务端打印结果
AIDL中使用Interface接口回调_第1张图片

你可能感兴趣的:(android,aidl,android-aidl)