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,一经查实,立即删除!

相关文章

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;而不用实现全部接口方法。 适配…

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工程运…

CISCRISC? CPU架构有哪些? x86 ARM?

编者按&#xff1a;鉴于笔者水平有限&#xff0c;文中难免有不当之处&#xff0c;还请各位读者海涵。 是为序 我猜&#xff0c;常年混迹CSDN的同学应该不会没听说过CPU吧&#xff1f; 但你真的了解CPU吗&#xff1f;那笔者问你CPU有哪些架构呢&#xff1f; 如果你对你的答案…

FCIS 2023:洞悉网络安全新态势,引领创新防护未来

随着网络技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;成为全球共同关注的焦点。在这样的背景下&#xff0c;FCIS 2023网络安全创新大会应运而生&#xff0c;旨在汇聚业界精英&#xff0c;共同探讨网络安全领域的最新动态、创新技术和解决方案。 本文将从大会的…

JVM 性能调优 - Java 中的四种引用(4)

为什么会有四种引用 我们先回顾下在 Java 虚拟机内存体系(1) 中提到了的垃圾回收算法 1、引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它,计数器的值就加一。每当有一个引用失效,计数器的值就减一。当计数器值为零时,这个对象被认为没有其他对象引用,…

JDK和Spring的SPI机制原理分析

目录 一、JDK 二、Spring框架介绍 三、SPI机制原理 一、JDK JDK是Java Development Kit的缩写&#xff0c;是Java开发工具包的意思。它是用于开发Java应用程序和运行Java程序的软件包。JDK包含了Java编译器&#xff08;javac&#xff09;和Java虚拟机&#xff08;JVM&#…

【快速上手QT】01-QWidgetQMainWindow QT中的窗口

总所周知&#xff0c;QT是一个跨平台的C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序&#xff0c;当然我们用到QT就是要做GUI的&#xff0c;所以我们快速上手QT的第一篇博文就讲QT的界面窗口。 我用的IDE是VS2019&#xff0c;使用QTc…

【NodeJS】005- MongoDB数据库

1.简介 1.1 Mongodb 是什么 MongoDB 是一个基于分布式文件存储的数据库&#xff0c;官方地址 https://www.mongodb.com/ 1.2 数据库是什么 数据库&#xff08;DataBase&#xff09;是按照数据结构来组织、存储和管理数据的 应用程序 1.3 数据库的作用 数据库的主要作用就是…