Android开发:基于 Kotlin 协程的设备指令控制工具类设计与实现

在安卓开发中,设备控制是一个常见的需求。本文将介绍如何使用 Kotlin 协程实现一个高效、健壮的设备指令控制工具类。该工具类支持指令队列、重试机制、状态管理等功能,并适配安卓平台,确保生命周期管理和主线程安全性。通过本文,你将学习到如何设计一个可扩展的工具类,并将其集成到安卓项目中。

库引入

build.gradle 文件中添加以下依赖:

dependencies {implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0" // Kotlin 协程implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0" // 安卓协程支持implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1" // ViewModel 支持implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1" // Lifecycle 支持
}

完整代码

1. 工具类代码
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow/*** 指令发送工具类(适配安卓平台)** @param sendCommand 发送指令的函数,返回指令是否成功* @param config 工具类配置*/
class CommandSender(private val sendCommand: suspend (Command) -> Response,private val config: CommandSenderConfig = CommandSenderConfig()
) {// 指令队列private val commandChannel = Channel<Command>(capacity = Channel.UNLIMITED)// 指令状态流private val _commandStateFlow = MutableSharedFlow<CommandState>(replay = 1)val commandStateFlow = _commandStateFlow.asSharedFlow()// 协程作用域(使用 SupervisorJob)private val scope = CoroutineScope(config.dispatcher + SupervisorJob())// 是否正在运行private var isRunning = trueinit {// 启动指令处理协程scope.launch {for (command in commandChannel) {if (!isRunning) break // 如果工具类已关闭,停止处理sendCommandWithRetry(command)}}}/*** 添加指令到队列*/fun addCommand(command: Command) {if (!isRunning) throw IllegalStateException("CommandSender is already closed")scope.launch {commandChannel.send(command)}}/*** 发送指令并重试*/private suspend fun sendCommandWithRetry(command: Command, retryCount: Int = 0, currentDelay: Long = config.retryDelay) {log("Sending command: ${command.id}, retryCount: $retryCount")val response = try {sendCommand(command)} catch (e: Exception) {log("Command ${command.id} failed with exception: ${e.message}")Response(command.id, false)}if (response.isSuccess) {log("Command ${command.id} succeeded")_commandStateFlow.emit(CommandState.Success(command))} else if (retryCount < config.maxRetries - 1) {log("Retrying command: ${command.id}")delay(currentDelay)sendCommandWithRetry(command, retryCount + 1, currentDelay * 2) // 指数退避} else {log("Command ${command.id} failed after ${config.maxRetries} retries")_commandStateFlow.emit(CommandState.Failed(command))}}/*** 清理资源*/fun cleanup() {isRunning = falsescope.cancel("CommandSender is shutting down")commandChannel.close()log("CommandSender resources cleaned up")}/*** 日志记录*/private fun log(message: String) {println("CommandSender: $message") // 替换为实际日志工具}
}/*** 工具类配置*/
data class CommandSenderConfig(val maxRetries: Int = 3,val retryDelay: Long = 300,val dispatcher: CoroutineDispatcher = Dispatchers.IO
)/*** 指令数据类*/
data class Command(val id: String, val data: String, val priority: Int = 0)/*** 指令响应数据类*/
data class Response(val commandId: String, val isSuccess: Boolean)/*** 指令状态密封类*/
sealed class CommandState {data class Pending(val command: Command, val retryCount: Int = 0) : CommandState()data class Success(val command: Command) : CommandState()data class Failed(val command: Command, val error: Throwable? = null) : CommandState()data class Timeout(val command: Command) : CommandState()data class Cancelled(val command: Command) : CommandState()
}

2. 在 ViewModel 中使用工具类
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launchclass DeviceControlViewModel : ViewModel() {// 创建 CommandSender 实例private val commandSender = CommandSender(sendCommand = { command ->// 模拟发送指令并接收回码delay(100) // 模拟网络延迟Response(command.id, Math.random() > 0.5) // 随机返回成功或失败})// 暴露指令状态流val commandStateFlow: SharedFlow<CommandState> = commandSender.commandStateFlow/*** 添加指令*/fun addCommand(command: Command) {viewModelScope.launch {commandSender.addCommand(command)}}/*** 清理资源*/override fun onCleared() {super.onCleared()commandSender.cleanup()}
}

3. 在 ActivityFragment 中观察状态
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collectclass DeviceControlActivity : AppCompatActivity() {private val viewModel: DeviceControlViewModel by viewModels()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 监听指令状态lifecycleScope.launch {viewModel.commandStateFlow.collect { state ->when (state) {is CommandState.Success -> {// 更新 UI:指令成功println("Command ${state.command.id} succeeded")}is CommandState.Failed -> {// 更新 UI:指令失败println("Command ${state.command.id} failed")}else -> {}}}}// 添加指令viewModel.addCommand(Command("1", "Turn on"))viewModel.addCommand(Command("2", "Turn off"))}
}

总结

通过本文,我们实现了一个基于 Kotlin 协程的设备指令控制工具类。该工具类支持指令队列、重试机制、状态管理等功能,并适配安卓平台,确保生命周期管理和主线程安全性。希望这篇博客对你有所帮助!

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

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

相关文章

关于在vscode中的Linux 0.11 应用程序项目的生成和运行

首先我们需要需要查看镜像文件 查看软盘镜像文件 floppyb.img 中的内容 在 VSCode 的“Terminal”菜单中选择“Run Build Task...”&#xff0c;会在 VSCode 的顶部中间位置弹出一个 可以执行的 Task 列表&#xff0c;选择其中的“打开 floppyb.img”后会使用 Floppy Editor …

【JavaScript 简明入门教程】为了Screeps服务的纯JS入门教程

0 前言 0-1 Screeps: World 众所不周知&#xff0c;​Screeps: World是一款面向编程爱好者的开源大型多人在线即时战略&#xff08;MMORTS&#xff09;沙盒游戏&#xff0c;其核心机制是通过编写JavaScript代码来控制游戏中的单位&#xff08;称为“Creep”&#xff09;&#…

【CSS文字渐变动画】

CSS文字渐变动画 HTML代码CSS代码效果图 HTML代码 <div class"title"><h1>今天是春分</h1><p>正是春天到来的日子&#xff0c;花都开了&#xff0c;小鸟也飞回来了&#xff0c;大山也绿了起来&#xff0c;空气也有点嫩嫩的气息了</p>…

【论文阅读】基于思维链提示的大语言模型软件漏洞发现与修复方法研究

这篇文章来自于 Chain-of-Thought Prompting of Large Language Models for Discovering and Fixing Software Vulnerabilities 摘要 软件安全漏洞在现代系统中呈现泛在化趋势&#xff0c;其引发的社会影响日益显著。尽管已有多种防御技术被提出&#xff0c;基于深度学习&…

SpringMVC_day02

一、SSM 整合 核心步骤 依赖管理 包含 SpringMVC、Spring JDBC、MyBatis、Druid 数据源、Jackson 等依赖。注意点&#xff1a;确保版本兼容性&#xff08;如 Spring 5.x 与 MyBatis 3.5.x&#xff09;。 配置类 SpringConfig&#xff1a;扫描 Service 层、启用事务管理、导入…

基于ADMM无穷范数检测算法的MIMO通信系统信号检测MATLAB仿真,对比ML,MMSE,ZF以及LAMA

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 ADMM算法 4.2 最大似然ML检测算法 4.3 最小均方误差&#xff08;MMSE&#xff09;检测算法 4.4 迫零&#xff08;ZF&#xff09;检测算法 4.5 OCD_MMSE 检测算法 4.6 LAMA检测算法 …

CSS动画

目录 一、核心概念与语法 1. keyframes 关键帧 2. animation 属性 二、动画调速函数&#xff08;animation-timing-function&#xff09; 1. 预设值 2. 贝塞尔曲线 3. 步进函数&#xff08;steps()&#xff09; 三、动画控制与交互 1. 暂停与恢复 2. JavaScript 控制…

架构思维:预约抢茅子架构设计

文章目录 案例&#xff1a;预约抢茅子复杂度分析商品预约阶段等待抢购阶段商品抢购阶段订单支付阶段 技术方案商品预约阶段一、基于 Redis 单节点的分布式锁方案1. 核心流程2. 关键设计点 二、Redis 单节点方案的局限性1. 单点故障风险2. 主从切换问题 三、多节点 Redis 实现高…

PHP大马的使用

BestShell/best_php_shell.php at master Kevil-hui/BestShell 这里用到的是这位师傅的大马&#xff08;主要是从头开始写一个大马实在太麻烦了&#xff09; 用pikachu靶场进行上传的测试 在这里传马&#xff0c;这个是简单的前端校验&#xff0c;bp抓包改后缀就好了 上传成…

HCI 清除 SCP纳管残留信息

项目场景&#xff1a; 一台测试HCI主机&#xff0c;之前有连接了SCP&#xff0c;由于环境变更&#xff0c;无法与SCP连通&#xff0c;HCI残留了SCP纳管信息 问题描述 集群管理中没有脱离SCP的选项 点击vmware 虚拟机 显示被接管 云安全中心也显示被接管 原因分析&#xff1a; …

【算法day22】两数相除——给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。

29. 两数相除 给你两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断&#xff0c;也就是截去&#xff08;truncate&#xff09;其小数部分。例如&#xff0c;8.345 将被截断为 8 &#x…

顺序表(C语言源码详解,附加测试代码)

目录 顺序表的基本实现 顺序表结构 顺序表的初始化 检查顺序表容量空间 顺序表的头插 顺序表的打印 顺序表的头删 顺序表的尾插 顺序表的尾删 顺序表的查找 ​编辑指定位置之前插入数据 指定位置删除数据 顺序表的销毁 顺序表的基本实现 顺序表结构 对顺序表的数…

draw.io费的思维导图软件、支持ProcessOn无水印导出。

draw.io的官方网址是 https://www.drawio.com/ 通过官方下载&#xff0c;本文只是安装及使用教程。 一、从别的思维导图软件导出并导入到Draw.io&#xff0c;&#xff08;ProcessOn为例&#xff09; 选择要付费下载流程图&#xff0c;并以ViSio格式导出&#xff08;后缀名…

springboot启动事件CommandLineRunner使用

什么是CommandRunner CommandRunner是springboot启动完成时会调用的一个runner 启动参数会传递到这个runner 我们能用来做一些初始化工作和缓存预热等工作 ApplicationRunner VS CommandRunner? 这两个Runner作用一样 只是得到的启动参数格式不一样 前者是一个Argument对象…

能源革命新突破:虚拟电厂赋能微电网智能调控,构建低碳生态新格局

在“双碳”目标的引领下&#xff0c;中央一号文件明确提出了“推进农村能源革命&#xff0c;深化绿色低碳技术应用”。作为能耗集中区域&#xff0c;产业园区如何实现清洁能源高效消纳与碳减排的目标成为了难题&#xff0c;中电国为推出的虚拟电厂与风光储充柴多能互补的微电网…

LabVIEW FPGA与Windows平台数据滤波处理对比

LabVIEW在FPGA和Windows平台均可实现数据滤波处理&#xff0c;但两者的底层架构、资源限制、实时性及应用场景差异显著。FPGA侧重硬件级并行处理&#xff0c;适用于高实时性场景&#xff1b;Windows依赖软件算法&#xff0c;适合复杂数据处理与可视化。本文结合具体案例&#x…

智慧高速,安全护航:视频监控平台助力高速公路高效运营

随着我国高速公路里程的不断增长&#xff0c;交通安全和运营效率面临着前所未有的挑战。传统的监控方式已难以满足现代化高速公路管理的需求&#xff0c;而监控视频平台的出现&#xff0c;则为高速公路的安全运营提供了强有力的技术支撑。高速公路视频监控联网解决方案 高速公路…

聚焦能源数字化转型,遨游通讯携智能化防爆手机亮相cippe2025

2025年3月26日&#xff0c;第二十五届中国国际石油石化技术装备展览会在北京中国国际展览中心&#xff08;新馆&#xff09;盛大开幕。作为全球石油石化行业的年度盛会&#xff0c;cippe2025北京石油展汇聚了来自全球75个国家和地区的近2000家企业&#xff0c;共同展示最新的石…