AIDL(2):服务端回调客户端
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):服务端回调客户端的更多相关文章
- 解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)
由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...
- WCF心跳判断服务端及客户端是否掉线并实现重连接
WCF心跳判断服务端及客户端是否掉线并实现重连接 本篇文章将通过一个实例实现对WCF中针对服务端以及客户端是否掉线进行判断:若掉线时服务器或客户端又在线时将实现自动重连:将通过WCF的双工知识以及相应 ...
- Java的oauth2.0 服务端与客户端的实现
oauth原理简述 oauth本身不是技术,而是一项资源授权协议,重点是协议!Apache基金会提供了针对Java的oauth封装.我们做Java web项目想要实现oauth协议进行资源授权访问,直 ...
- oauth2.0服务端与客户端搭建
oauth2.0服务端与客户端搭建 - 推酷 今天搭建了oauth2.0服务端与客户端.把搭建的过程记录一下.具体实现的功能是:client.ruanwenwu.cn的用户能够通过 server.ru ...
- 使用WebSocket实现服务端和客户端的通信
开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...
- Java 断点下载(下载续传)服务端及客户端(Android)代码
原文: Java 断点下载(下载续传)服务端及客户端(Android)代码 - Stars-One的杂货小窝 最近在研究断点下载(下载续传)的功能,此功能需要服务端和客户端进行对接编写,本篇也是记录一 ...
- asp.net获取服务端和客户端信息
asp.net获取服务端和客户端信息 获取服务器名:Page.Server.ManchineName获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostNam ...
- python thrift 服务端与客户端使用
一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...
- IE8下服务端获取客户端文件的路径为C:/fakePath问题的解决方案
上一篇文章上提到,IE8下服务端获取客户端文件的路径时,会变成C:/fakePath问题,于是乎通过文件路径去获得文件大小就失败了. 上网搜了一下,主要原因是IE8因为安全考虑,在上传文件时屏蔽了真实 ...
随机推荐
- (转)Linux环境进程间通信系列(五):共享内存
原文地址:http://www.cppblog.com/mydriverc/articles/29741.html 共享内存可以说是最有用的进程间通信方式,也是最快的 IPC 形式.两个不同进程 A ...
- Android Hander、Looper、Message三者之间的联系
1.首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象:因为Looper.prepare()在一个线程中只能调用一次,所以Mess ...
- Android绘图之Matrix
一.概述 1. 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下 2.Matrix的对图像的处理 ...
- [转]-webkit-overflow-scrolling:touch的应用
-webkit-overflow-scrolling 用来控制元素在移动设备上是否使用滚动回弹效果. 在移动端上,在你用overflow-y:scorll属性的时候,你会发现滚动的效果很木,很慢,这时 ...
- 关于CS0016: Could not write to output file ‘c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary AS
1.添加用户"Network Service” 和 “IIS_IUSERS” 读下面目录的读写权限 a) C:\Windows\Temp b) C:\Windows\Microsoft.NE ...
- [Essay]看《Re:从零开始的异世界生活》的一些感想
人生不能重来,但动漫可以. -- 故事背景 <介绍背景> 男主486通过不断重来,而改变了剧情的发展.整个动漫就像RPG游戏一般,只看了一遍没有完全理解,但后来再看萌娘百科才把整个剧情里所 ...
- IO模型《二》阻塞IO
阻塞IO(blocking IO) 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样: 当用户进程调用了recvfrom这个系统调用,kernel就开始 ...
- 51 nod 1267 4个数和为0
1267 4个数和为0 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 取消关注 给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出& ...
- 推荐分享一个牛X的自定义PHP加密解密类
通俗点说,用它来进行加密,同一个字符串,每次进行加密,得出的结果都是不一样的,大大加强了数据安全性.同时还可设定加密后数据的有效期,简直牛掰了 #食用方法 将下面的第二份模块代码保存为 Mcrypt. ...
- flex弹性布局,好用
一直不太喜欢自己布局前端页面,都是扒别人的页面 ,最近在练习小程序,页面无处可扒,只有自己布局 发现flex弹性布局真好用,布局起来很简单,实现的效果也很好,赞 以后可以自己写一点前端了,哈哈