aidl复杂流程封装

1 aidl相关困扰点


1 制作步骤复杂,先定义然后编译,然后复制,两边都要一一对应
2 增加回调,自定义对象流程更加麻烦,还要处理对象数据流是 in 还是out。
3 一方异常怎么办,虽然服务端可以用 RemoteCallbackList 客户端可以用DeathRecipient来处理,但很麻烦
4 考虑服务端一对多时候,需要一对一发送消息
很累很麻烦,使用还不方便,所以我必须设计一个aar包,将这些细节全都封进去,以后再也不关心这些破玩意了

2 解决方案

1 为了应对各种对象,统一转为string进行传输(可通过json等转成对应的对象)
2 通过添加封装类对 aidl的连接流程进行封装,本地的也封装以下(虽然本地的bind可以直接进程内通信)
3 传输监听对象时,需要传输一个唯一值 ,通过map保存该唯一值。这样就可以通过key值进行针对性传输,也可以找到该监听类,不再通过RemoteCallbackList来移除监听类了。

4 提供异步和同步访问,因为有些操作同步会导致 service 卡顿(四大组件之一的服务是运行在主线程),所以是需要提供下异步操作的。

3 实现

接下来看下大概的类图吧,然后下一步就是具体的实现了。

先来看下本地服务类代码:
public abstract class AsynService extends Service {protected static final String TAG = "JsonProtocolService";protected WorkThread worker;public void onCreate() {super.onCreate();if (this.worker == null || !this.worker.isRunning()) {this.worker = new WorkThread();this.worker.start();}}public void onDestroy() {super.onDestroy();if (this.worker != null && this.worker.isRunning()) {this.worker.interrupt();this.worker = null;}}protected String getRequestAuthor(String params) {String requestAuthor = null;try {JSONObject jsonObject = new JSONObject(params);if (jsonObject.has(SDKConstants.KEY_CLIENT_REQUEST_AUTHOR)) {requestAuthor = jsonObject.optString(SDKConstants.KEY_CLIENT_REQUEST_AUTHOR);}} catch (JSONException e) {Log.e(TAG, "getRequestAuthor: ", e);}return requestAuthor;}protected void offerReq(JsonProtocolManager.Message message) {this.worker.offerReq(message);}//具体实现接口抽象出来给外部实现public interface ServiceCallback {void onEvent(int event, String msg);void received(String params, Bundle bundle);String receivedSync(String params, Bundle bundle);}protected static class WorkThread extends Thread {private static final Object syncObj = new Object();private final LinkedBlockingQueue<JsonProtocolManager.Message> msgLBQ = new LinkedBlockingQueue<>();private boolean isRunning = false;private ServiceCallback serviceCallback;public void init(ServiceCallback callback) {synchronized(syncObj) {this.serviceCallback = callback;syncObj.notify();}}public void onEvent(int event, String msg) {synchronized(syncObj) {if (this.serviceCallback != null) {this.serviceCallback.onEvent(event, msg);}}}public void offerReq(JsonProtocolManager.Message message) {this.msgLBQ.offer(message);}public void run() {this.isRunning = true;while (this.isRunning) {try {JsonProtocolManager.Message msg = this.msgLBQ.take();synchronized(syncObj) {while (this.serviceCallback == null) {syncObj.wait();}}if (!this.onReceive(msg)) {this.msgLBQ.offer(msg);}} catch (Exception e) {e.printStackTrace();}}}boolean isRunning() {return this.isRunning;}private boolean onReceive(JsonProtocolManager.Message message) {synchronized(syncObj) {if (this.serviceCallback != null) {LogUtils.e(TAG, "receive  params=" + message.mParams);this.serviceCallback.received(message.mParams, message.mBundle);return true;} else {return false;}}}}protected ServiceCallback mServiceCallback;public void setServiceCallback(ServiceCallback mLocalCallback) {this.mServiceCallback = mLocalCallback;}abstract void send(JsonProtocolManager.Message message);abstract String sendSync(String params, Bundle bundle);//本地bind,进程内通信public class ServiceBinder extends Binder {public void setServiceCallback(ServiceCallback callback) {AsynService.this.setServiceCallback(callback);AsynService.this.worker.init(callback);}public void send(JsonProtocolManager.Message message) {AsynService.this.send(message);}public String sendSync(String params, Bundle bundle) {return AsynService.this.sendSync(params, bundle);}}
}

再来看下 实现类:

public class AidlService extends AsynService {private static final String TAG = "JsonProtocolService";private final HashMap<String, ICallback> mCallbacksMap = new HashMap<String, ICallback>();private final ServiceBinder localBinder = new ServiceBinder();private final IServiceBinder.Stub remoterBinder = new IServiceBinder.Stub() {@Overridepublic int register(int versionCode, String caller, ICallback callback) {LogUtils.d(TAG, "register: versionCode = " + versionCode + " , caller = " + caller);mCallbacksMap.put(caller, callback);//remoteCallbackList.register(callback);worker.onEvent(SDKConstants.EVENT_CLIENT_CONNECTED, "client is connected!");return SDKConstants.VERSION_CODE;}@Overridepublic void received(String params, Bundle bundle) {JsonProtocolManager.Message message = new JsonProtocolManager.Message(params, bundle);offerReq(message);}@Overridepublic String receivedSync(String params, Bundle bundle) {return mServiceCallback == null ? "" : mServiceCallback.receivedSync(params, bundle);}@Overridepublic void unregister(String caller, ICallback callback) {mCallbacksMap.remove(caller);//remoteCallbackList.unregister(callback);worker.onEvent(SDKConstants.EVENT_CLIENT_DISCONNECTED, "client is disconnected!");}};@Overridepublic IBinder onBind(Intent intent) {LogUtils.d(TAG, "onBind");if (intent != null && intent.hasExtra(SDKConstants.CONNECT_EXTRA_KEY)) {String from = intent.getStringExtra(SDKConstants.CONNECT_EXTRA_KEY);if (SDKConstants.CONNECT_EXTRA_VALUE_LOCAL.equals(from)) {LogUtils.d(TAG, "onBind:local");return this.localBinder;}if (SDKConstants.CONNECT_EXTRA_VALUE_REMOTER.equals(from)) {LogUtils.d(TAG, "onBind:remoter");return this.remoterBinder;}}return null;}@Overrideprotected void send(JsonProtocolManager.Message message) {try {int N = mCallbacksMap.size();if (N > 0) {LogUtils.e(TAG, "send params=" + message.mParams);ICallback l = null;String requestAuthor = getRequestAuthor(message.mParams);if (mCallbacksMap.size() > 0 && !TextUtils.isEmpty(requestAuthor)) {l = mCallbacksMap.get(requestAuthor);}if (l != null) {l.received(message.mParams, message.mBundle);}else {Log.e(TAG, "send: client is NOT connected:" + requestAuthor);}} else if (N == 0) {Log.e(TAG, "send: client is NOT connected");}} catch (Exception e) {LogUtils.e(TAG, "send params=" + message.mParams);}}@Overrideprotected String sendSync(String params, Bundle bundle) {try {int N = mCallbacksMap.size();if (N > 0) {LogUtils.e(TAG, "send params=" + params);ICallback l = null;String requestAuthor = getRequestAuthor(params);if (mCallbacksMap.size() > 0 && !TextUtils.isEmpty(requestAuthor)) {l = mCallbacksMap.get(requestAuthor);}if (l != null) {return l.receivedSync(params, bundle);} else {Log.e(TAG, "sendSync: client is NOT connected:" + requestAuthor);}} else if (N == 0) {Log.e(TAG, "sendSync: client is NOT connected");}} catch (Exception e) {LogUtils.e(TAG, "send params=" + params);}return null;}}

下次再来接下来的manager类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/669157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UI自动化中元素无法定位问题解决方法

元素无法定位问题解决方法 1、display屏蔽元素2、iframe内元素无法定位3、 根据部分元素属性定位4、页面跳转到新的标签页&#xff0c;或者弹出的警告框等6、使用WebDriver调用JavaScript代码代替无法实现的功能 1、display屏蔽元素 分析一下html的display属性&#xff0c;可以…

计算机网络(复习资料)

1.互联网的两个重要基本特点 连通性和共享性 2.计算机网络由若干节点和连接这些节点的链路组成 3.有多个网络通过路由器相互连接起来,构成一个更大的计算机网络称为互联网 4.网络把许多计算机连接在一起,互联网把许多网络通过一些路由器连接在一起,与网络相连的计算机称为…

web应用课——(第五讲:React)

目录 一、配置环境 二、ES6语法补充 三、Components 四、组合Components 五、路由 六、Redux 一、配置环境 感谢z神&#xff08;zst_2001&#xff09;的分享&#xff1a; git下载与安装Node.js下载与安装React下载与安装 二、ES6语法补充 使用bind()函数绑定this取值&…

haiku实现TemplatePairStack类

TemplatePairStack是实现蛋白质结构模版pair_act特征表示的类: 通过layer_stack.layer_stack(c.num_block)(block) 堆叠c.num_block(配置文件中为2)block 函数,每个block对输入pair_act 和 pair_mask执行计算流程:TriangleAttention —> dropout ->TriangleAttentio…

Retrofit源码分析及理解

参考文档&#xff1a; 12W字&#xff1b;2022最新Android11位大厂面试专题&#xff08;一&#xff09; - 掘金 Retrofit 版本号&#xff1a;2.9.0 Retrofit简单来说&#xff0c;就是对OkHttp上层进行了封装&#xff0c;已达到用户方便使用管理网络请求的目的。 Retrofit内部有…

力扣热门100题刷题笔记 - 10. 正则表达式匹配

力扣热门100题 - 10. 正则表达式匹配 题目链接&#xff1a;10. 正则表达式匹配 题目描述&#xff1a; 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配&#xff…

asqlcell,一个超强的 Python 库!

前言 大家好&#xff0c;今天为大家分享一个超强的 Python 库 - asqlcell。 Github地址&#xff1a;https://github.com/datarho/asqlcell Python asqlcell 是一个用于执行异步数据库操作的开源库&#xff0c;它允许开发者通过异步的方式与数据库进行交互&#xff0c;提高了数…

如何使用VS Code编写小游戏并实现公网游玩本地游戏【内网穿透】

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…

七月论文审稿GPT第2.5版:微调GPT3.5 turbo 16K和llama2 13B以扩大对GPT4的优势

前言 自去年7月份我带队成立大模型项目团队以来&#xff0c;我司至今已有5个项目组&#xff0c;其中 第一个项目组的AIGC模特生成系统已经上线在七月官网第二项目组的论文审稿GPT则将在今年3 4月份对外上线发布第三项目组的RAG知识库问答第1版则在春节之前已就绪至于第四、第…

ai平滑工具的使用方法

ai中想要使用平滑工具来处理线条&#xff0c;该怎么是哦用哪个恩&#xff1f;下面我们就来看看详细的教程。 1、我们通过一个例子演示平滑工具的使用&#xff0c;先新建文件&#xff0c;在左侧工具箱中找到平滑工具。 文章源自四五设计网-https://www.45te.com/39726.html 2、…

CSS:三列布局

三列布局是指左右两列定宽&#xff0c;中间自适应。最终效果如下&#xff1a; HTML&#xff1a; <div class"container"><div class"left"></div><div class"center"></div><div class"right">…

001集:open语句打开文件及文件类型(二进制、文本文件)详解——vba

open用法可以用来打开文件、文件夹或网页&#xff0c;也可以用来运行某一应用程序、文件或网页。一般来说&#xff0c;只要在开始菜单中可以找到某个应用程序&#xff0c;我们就可以使用open命令打开该应用程序;另外&#xff0c;在打开某个文件或网页时&#xff0c;也可以使用o…

设计模式学习笔记05(小滴课堂)

讲解Adapeter设计模式和应用场景 接口的适配器案例实战 代码&#xff1a; 定义一个接口&#xff1a; 编写适配器&#xff1a; 写我们的商品类&#xff1a; 会员类&#xff1a; 这样我们不同的需求可以根据需要去实现不同的接口方法&#xff0c;而不用实现全部接口方法。 适配…

如何预防最新的.kat6.l6st6r 勒索病毒感染您的计算机?

导言&#xff1a; 随着科技的不断进步&#xff0c;勒索病毒成为网络犯罪中一种极为破坏性的工具。其中&#xff0c;.kat6.l6st6r 勒索病毒作为最新的威胁之一&#xff0c;采用先进的加密算法&#xff0c;使用户的数据文件无法正常访问。本文91数据恢复将深入介绍这一勒索病毒的…

Qt案例 在对QGraphicsView视图修改和撤销修改图元操作时,使用命令模式实现。

当项目中有QGraphicsView视图直接修改图元的功能时&#xff0c;常会有CtriZ和CtrlY这种执行与撤销图元修改的功能&#xff0c;以便于在修改图元后能够进行一个还原/执行操作&#xff0c;此时就适合使用命令模式设计来实现这个功能。 以下示例在WINDOWS系统&#xff0c;Qt Creat…

echarts step line

https://ppchart.com/#/ <template><div class"c-box" ref"jsEchart"></div> </template><script> import * as $echarts from echarts // 事件处理函数 export default {props: {// 需要传递的数据data: {type: Array,defa…

字符串匹配算法(z函数模版)来自灵神。

一个字符串s求出s的z[i]&#xff0c;z[i]表示以s[i:n]这一段和s[0:n]的从前往后的连续相等字母个数。 比如 abacaba,z[2] (acaba与abacaba比较) 1。

SpringBoot整合Flowable最新教程(一)Flowable介绍

一、Flowable 入门介绍 代码实现文章&#xff1a;SpringBoot整合Flowable最新教程&#xff08;二&#xff09; 官网地址&#xff1a;https://www.flowable.org/   Flowable6.3中文教程&#xff1a;中文教程地址   可以在官网下载对应的jar包在本地部署运行&#xff0c;官方…

【IC设计】Windows下基于IDEA的Chisel环境安装教程(图文并茂)

Chisel环境安装教程 第一步 安装jdk&#xff0c;配置环境变量第二步 安装sbt&#xff0c;不用配置环境变量第三步 安装idea社区版第四步 离线安装scala的idea插件第五步 配置sbt换源1.切换目录2.创建repositories文件3.配置sbtconfig.txt文件 第六步 使用chisel-tutorial工程运…

什么是边缘计算?

今天&#xff0c;我们探讨一个充满机遇和挑战的领域——边缘计算。 首先&#xff0c;让我们一起探讨一下什么是边缘计算。简单来说&#xff0c;边缘计算是指在网络的边缘&#xff0c;即数据生成的位置进行计算的一种模式。这与传统的云计算模式形成了鲜明对比&#xff0c;在云…