原生 Android(Kotlin)仅串口「可插拔架构」完整案例一

张开发
2026/4/8 16:50:52 15 分钟阅读

分享文章

原生 Android(Kotlin)仅串口「可插拔架构」完整案例一
原生 AndroidKotlin仅串口「可插拔架构」完整案例和你 Flutter 那套架构逻辑一模一样抽象接口 → 实现类 → 业务层调用 → 完全解耦、易维护、可替换一、整体架构对标你 Flutter抽象接口 ISerial定标准不变实现类 SerialImpl对接原生串口SDK可替换工具注入/组合使用Activity 直接调用无耦合第一步定义抽象接口ISerial.kt对应 Flutteri_serial.dart/** * 串口统一抽象标准 * 所有串口实现必须遵守这个规范 */interfaceISerial{// 获取可用串口列表suspendfungetPortList():ListString// 打开串口suspendfunopenPort(portName:String,baudRate:Int9600):Boolean// 发送字符串数据suspendfunsendData(text:String)// 接收串口数据流funreceiveStream():kotlinx.coroutines.flow.FlowString// 关闭串口funclosePort()// 销毁资源funrelease()}第二步串口具体实现类SerialImpl.kt对接 Android 原生串口USB/串口库后续换串口库只改这里业务不动importkotlinx.coroutines.delayimportkotlinx.coroutines.flow.Flowimportkotlinx.coroutines.flow.flow/** * 串口实际业务实现 * 可随时替换底层USB串口SDK上层代码零改动 */classSerialImpl:ISerial{// 模拟串口连接状态真实项目替换成原生USB串口实例privatevarisConnectedfalse// 模拟获取串口列表overridesuspendfungetPortList():ListString{delay(300)returnlistOf(/dev/ttyUSB0,/dev/ttyUSB1,COM3)}// 模拟打开串口overridesuspendfunopenPort(portName:String,baudRate:Int):Boolean{delay(500)isConnectedtrueprintln(【串口】打开成功$portName波特率$baudRate)returntrue}// 发送数据overridesuspendfunsendData(text:String){if(!isConnected)returnprintln(【串口发送】$text)// 真实项目转为字节数组写入串口}// 模拟接收数据流Flow 对标 Flutter StreamoverridefunreceiveStream():FlowStringflow{while(isConnected){delay(1000)emit(串口回传模拟数据${System.currentTimeMillis()})}}// 关闭串口overridefunclosePort(){isConnectedfalseprintln(【串口】已关闭)}// 释放资源overridefunrelease(){closePort()}}第三步封装统一管理类可选全局单例对标你 Flutter 全局插拔管理/** * 串口全局管理器——即插即用 */objectSerialManager{// 注入实现类想换实现直接改这里valserial:ISerialSerialImpl()}第四步Activity 业务层使用最简、零耦合页面完全不关心底层串口怎么实现只调用标准方法importandroidx.appcompat.app.AppCompatActivityimportandroid.os.Bundleimportkotlinx.coroutines.CoroutineScopeimportkotlinx.coroutines.Dispatchersimportkotlinx.coroutines.launchclassSerialActivity:AppCompatActivity(){// 直接拿抽象接口能力底层无感privatevalserialSerialManager.serialoverridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_serial)// 示例获取串口列表CoroutineScope(Dispatchers.IO).launch{valportListserial.getPortList()println(可用串口$portList)// 打开串口valopenResultserial.openPort(/dev/ttyUSB0,9600)if(openResult){// 发指令serial.sendData(ATTEST)// 监听接收数据launch{serial.receiveStream().collect{println(收到串口数据$it)}}}}}overridefunonDestroy(){super.onDestroy()// 销毁释放资源规范必加serial.release()}}核心优势和你 Flutter 完全一致1. 真正可插拔换串口SDK → 只新建一个NewSerialImpl实现ISerial改一行注入Activity 不动2. 极高维护性后期改串口协议、换硬件、换驱动业务代码不用改3. 团队协作规范所有人都按ISerial标准调用不会写乱4. 跨端思想统一你 Flutter 学的架构原生 Android 直接照搬上手极速一句话总结你 Flutter 的接口实现插拔架构✅ 100% 适配原生 Android✅ 串口案例极简落地✅ 大幅提升开发效率 后期维护需要我再给你加Android 真实 USB 串口开源库usb-serial对接版替换模拟代码吗不习惯这样写第四步优化结构 *没问题我直接给你写最简洁、最标准、你想要的写法原生 Android 串口封装Activity 直接 implement 接口完全满足你class SerialActivity : AppCompatActivity(), ISerial不绕弯、不搞多余封装直接在页面实现接口调用干净利落1. 串口抽象接口定标准// 串口标准接口interfaceISerialPort{funopenPort(port:String,baudRate:Int):BooleanfunsendData(data:String)funclosePort()}2. Activity 直接实现接口你要的格式classSerialActivity:AppCompatActivity(),ISerialPort{// // 串口底层对象实际驱动// privatevarserialPort:SerialPort?nullprivatevaroutputStream:OutputStream?null// // 实现接口方法// overridefunopenPort(port:String,baudRate:Int):Boolean{returntry{// 打开串口Android 主流串口库serialPortSerialPort(port,baudRate,0)outputStreamserialPort!!.outputStreamtrue}catch(e:Exception){e.printStackTrace()false}}overridefunsendData(data:String){try{outputStream?.write(data.toByteArray())}catch(e:Exception){e.printStackTrace()}}overridefunclosePort(){try{outputStream?.close()serialPort?.close()}catch(e:Exception){}}// // 页面使用// overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_serial)// 直接调用自己实现的方法openPort(/dev/ttyS0,9600)sendData(Hello Serial)}overridefunonDestroy(){super.onDestroy()closePort()}} 你要的效果 100% 实现classSerialActivity:AppCompatActivity(),ISerialPort{// 页面自己实现串口方法// 页面自己调用串口方法}这种写法叫接口实现模式 页面接口下沉Activity 直接实现串口标准 → 自己实现 → 自己调用✅ 优点最简单没有任何多余封装直观串口逻辑全在页面里完全符合你想要的结构原生安卓最常用的基础封装

更多文章