1.大致流程

  • 在服务端声明远程服务接口IRemoteService.aidl,并声明回调接口ICallback.aidl
  • 在服务端实现远程服务接口IRemoteService.Stub
  • 使用RemoteCallbackList保存回调接口列表
  • 发布服务
  • 在客户端实现回调接口 ICallback.Stub
  • 绑定服务,注册回调接口
  • 调用服务
  • 远程服务从RemoteCallbackList中找到回调,然后调用.

2.服务端

2.1 声明服务接口IRemoteService.aidl

 // IRemoteService.aidl
 package com.example.ee.aidl;

 import com.example.ee.aidl.ICallback;

 interface IRemoteService {

     int getPid();
     oneway void fun1();
     void registerCallback(ICallback cb);
     void unregisterCallback(ICallback cb);
 }

2.2 声明回调接口ICallback.aidl

 // ICallback.aidl
 package com.example.ee.aidl;

 interface ICallback {
     oneway void fun2();
 }

2.3 实现服务,用 RemoteCallbackList 保存回调接口.

 package com.example.ee.aidl;

 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.support.annotation.Nullable;
 import android.util.Log;

 public class RemoteService extends Service {
     final String TAG = "RemoteService";

     private RemoteBinder binder = new RemoteBinder();
     private RemoteCallbackList<ICallback>  callbackList = new RemoteCallbackList<>();

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

     class RemoteBinder extends IRemoteService.Stub{

         void callback(){
             int count = callbackList.beginBroadcast();
             try {
                 ; i < count; i++) {
                     callbackList.getBroadcastItem(i).fun2();
                 }
             } catch (RemoteException e) {
                 Log.e(TAG, e.getMessage());
             } finally {
             }
             callbackList.finishBroadcast();
         }

         @Override
         public int getPid() throws RemoteException {
             return Process.myPid();
         }

         @Override
         public void fun1() throws RemoteException {
             Log.d(TAG, "fun1 in remote service ");
             callback();
         }

         @Override
         public void registerCallback(ICallback cb) throws RemoteException {
             callbackList.register(cb);
         }

         @Override
         public void unregisterCallback(ICallback cb) throws RemoteException {
             callbackList.unregister(cb);
         }
     }
 }

2.4 发布服务

 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.ee.aidl">

     <application
         android:allowBackup="false"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:name=".AidlApp"
         android:theme="@style/AppTheme">
         <!--<meta-data
             android:name="APP_CHANNEL"
             android:value="${APP_CHANNEL}" />
 -->
         <activity android:name=".MainActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />

                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <service android:name=".RemoteService" android:process=".RemoteService" android:exported="true"/>
     </application>

 </manifest>

3.客户端

3.1 实现回调接口

     private ICallback callback  = new ICallback.Stub(){

         @Override
         public void fun2() throws RemoteException {
             Log.d(TAG, "fun2 in client ");
         }
     };

3.2 绑定远程服务,注册回调

     private void bindRemoteService(){
         connection = new ServiceConnection() {
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
                 remoteService = IRemoteService.Stub.asInterface(service);
                 try {
                     remoteService.registerCallback(callback);
                 } catch (RemoteException e) {
                     e.printStackTrace();
                 }
             }

             @Override
             public void onServiceDisconnected(ComponentName name) {

             }
         };

         Intent intent = new Intent(this,RemoteService.class);
         boolean ret = bindService(intent,connection, BIND_AUTO_CREATE);
         if (!ret ){
             Log.e(TAG, "bindRemoteService: bind failed.");
         }
     }

3.3 调用远程服务

     public void onClick(View view){
         if(view.getId() == R.id.btn_call_remote){
             AidlApp app = (AidlApp) getApplication();
             if (app.remoteService != null){
                 try {
                     int pid = app.remoteService.getPid();
                     Log.d(TAG, "onServiceConnected: remote pid = " + pid);
                     app.remoteService.fun1();
                 } catch (RemoteException e) {
                     e.printStackTrace();
                 }
             }else {
                 Snackbar.make(view,"remote service unbinded",Snackbar.LENGTH_SHORT).show();
             }
         }
     }

4. 远程服务调用回调

     void callback(){
             int count = callbackList.beginBroadcast();
             try {
                 ; i < count; i++) {
                     callbackList.getBroadcastItem(i).fun2();
                 }
             } catch (RemoteException e) {
                 Log.e(TAG, e.getMessage());
             } finally {
             }
             callbackList.finishBroadcast();
     }

5.下载

  https://gitee.com/xi/RemoteCallbackList.git

AIDL(2):服务端回调客户端的更多相关文章

  1. 解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)

    由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...

  2. WCF心跳判断服务端及客户端是否掉线并实现重连接

    WCF心跳判断服务端及客户端是否掉线并实现重连接 本篇文章将通过一个实例实现对WCF中针对服务端以及客户端是否掉线进行判断:若掉线时服务器或客户端又在线时将实现自动重连:将通过WCF的双工知识以及相应 ...

  3. Java的oauth2.0 服务端与客户端的实现

    oauth原理简述 oauth本身不是技术,而是一项资源授权协议,重点是协议!Apache基金会提供了针对Java的oauth封装.我们做Java web项目想要实现oauth协议进行资源授权访问,直 ...

  4. oauth2.0服务端与客户端搭建

    oauth2.0服务端与客户端搭建 - 推酷 今天搭建了oauth2.0服务端与客户端.把搭建的过程记录一下.具体实现的功能是:client.ruanwenwu.cn的用户能够通过 server.ru ...

  5. 使用WebSocket实现服务端和客户端的通信

    开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...

  6. Java 断点下载(下载续传)服务端及客户端(Android)代码

    原文: Java 断点下载(下载续传)服务端及客户端(Android)代码 - Stars-One的杂货小窝 最近在研究断点下载(下载续传)的功能,此功能需要服务端和客户端进行对接编写,本篇也是记录一 ...

  7. asp.net获取服务端和客户端信息

    asp.net获取服务端和客户端信息 获取服务器名:Page.Server.ManchineName获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostNam ...

  8. python thrift 服务端与客户端使用

    一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...

  9. IE8下服务端获取客户端文件的路径为C:/fakePath问题的解决方案

    上一篇文章上提到,IE8下服务端获取客户端文件的路径时,会变成C:/fakePath问题,于是乎通过文件路径去获得文件大小就失败了. 上网搜了一下,主要原因是IE8因为安全考虑,在上传文件时屏蔽了真实 ...

随机推荐

  1. JPA注解解析

    最近学习hibernate注解形式配置POJO类,将注解的解析记下来,以备以后使用. 例1. @Entity@Table(name="user")  public class Fl ...

  2. MySQL性能调优与架构设计——第8章 MySQL数据库Query的优化

    第8章 MySQL数据库Query的优化 前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 ...

  3. Redis主从服务部署

    Redis__WindowsServer主从服务部署及调用实例       一.先谈谈单个Redis服务的安装         使用的redis是2.8.17版本,从官网下载解压缩后文件内容为:   ...

  4. RegExp正则表达式对象

    JavaScript的RegExp对象有两种创建方式,一种是字面量,一种是对象. var r = /pattern/attributes或者new RegExp(pattern, attributes ...

  5. C# web通信解决方案

    1.Socket 2.Socket and websocket(HTML5) 3.SignalR 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket ...

  6. CF165D Beard Graph

    $ \color{#0066ff}{ 题目描述 }$ 给定一棵树,有m次操作. 1 x 把第x条边染成黑色 2 x 把第x条边染成白色 3 x y 查询x~y之间的黑边数,存在白边输出-1 \(\co ...

  7. .net core UseHttpsRedirection() 正式环境无效

    莫名其妙遇到这样的问题.这样的配置在本地可以,正式环境就不行了. ··· public void Configure(IApplicationBuilder app, Microsoft.AspNet ...

  8. 【重要的css属性学习】看了乙醇的文章,统计了几个高star前端框架下,Css属性出现最多的,这里学习记录一下

    color background-color display margin-left border-color padding max-width margin-bottom width flex 待 ...

  9. VS2010 由于缺少调试目标"xx.exe"

    有两种可能会造成这种现像.A.配制属性出了问题. 一种方法:右击“解决方案”->“属性”,在弹出的“属性页”框中,选择左边的“配置属性”,在右边,将应用程序的生成那个框框勾上,二可能是这里的属性 ...

  10. 选课 树形背包dp

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...