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

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

和你 Flutter 那套架构逻辑一模一样

抽象接口 → 实现类 → 业务层调用 → 完全解耦、易维护、可替换

一、整体架构(对标你 Flutter)

  1. 抽象接口 ISerial(定标准,不变)
  2. 实现类 SerialImpl(对接原生串口SDK,可替换)
  3. 工具注入/组合使用(Activity 直接调用,无耦合)

第一步:定义抽象接口(ISerial.kt)

对应 Flutter i_serial.dart

kotlin 复制代码
/**
 * 串口统一抽象标准
 * 所有串口实现必须遵守这个规范
 */
interface ISerial {
    // 获取可用串口列表
    suspend fun getPortList(): List<String>

    // 打开串口
    suspend fun openPort(portName: String, baudRate: Int = 9600): Boolean

    // 发送字符串数据
    suspend fun sendData(text: String)

    // 接收串口数据流
    fun receiveStream(): kotlinx.coroutines.flow.Flow<String>

    // 关闭串口
    fun closePort()

    // 销毁资源
    fun release()
}

第二步:串口具体实现类(SerialImpl.kt)

对接 Android 原生串口(USB/串口库),后续换串口库只改这里,业务不动

kotlin 复制代码
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

/**
 * 串口实际业务实现
 * 可随时替换底层USB串口SDK,上层代码零改动
 */
class SerialImpl : ISerial {

    // 模拟串口连接状态(真实项目替换成原生USB串口实例)
    private var isConnected = false

    // 模拟获取串口列表
    override suspend fun getPortList(): List<String> {
        delay(300)
        return listOf("/dev/ttyUSB0", "/dev/ttyUSB1", "COM3")
    }

    // 模拟打开串口
    override suspend fun openPort(portName: String, baudRate: Int): Boolean {
        delay(500)
        isConnected = true
        println("【串口】打开成功:$portName,波特率:$baudRate")
        return true
    }

    // 发送数据
    override suspend fun sendData(text: String) {
        if (!isConnected) return
        println("【串口发送】$text")
        // 真实项目:转为字节数组写入串口
    }

    // 模拟接收数据流(Flow 对标 Flutter Stream)
    override fun receiveStream(): Flow<String> = flow {
        while (isConnected) {
            delay(1000)
            emit("串口回传模拟数据:${System.currentTimeMillis()}")
        }
    }

    // 关闭串口
    override fun closePort() {
        isConnected = false
        println("【串口】已关闭")
    }

    // 释放资源
    override fun release() {
        closePort()
    }
}

第三步:封装统一管理类(可选,全局单例)

对标你 Flutter 全局插拔管理

kotlin 复制代码
/**
 * 串口全局管理器------即插即用
 */
object SerialManager {
    // 注入实现类,想换实现直接改这里
    val serial: ISerial = SerialImpl()
}

第四步:Activity 业务层使用(最简、零耦合)

页面完全不关心底层串口怎么实现,只调用标准方法

kotlin 复制代码
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class SerialActivity : AppCompatActivity() {

    // 直接拿抽象接口能力,底层无感
    private val serial = SerialManager.serial

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_serial)

        // 示例:获取串口列表
        CoroutineScope(Dispatchers.IO).launch {
            val portList = serial.getPortList()
            println("可用串口:$portList")

            // 打开串口
            val openResult = serial.openPort("/dev/ttyUSB0", 9600)
            if (openResult) {
                // 发指令
                serial.sendData("AT+TEST")

                // 监听接收数据
                launch {
                    serial.receiveStream().collect {
                        println("收到串口数据:$it")
                    }
                }
            }
        }
    }

    override fun onDestroy() {
        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. 串口抽象接口(定标准)

kotlin 复制代码
// 串口标准接口
interface ISerialPort {
    fun openPort(port: String, baudRate: Int): Boolean
    fun sendData(data: String)
    fun closePort()
}

2. Activity 直接实现接口(你要的格式)

kotlin 复制代码
class SerialActivity : AppCompatActivity(), ISerialPort {

    // ========================
    // 串口底层对象(实际驱动)
    // ========================
    private var serialPort: SerialPort? = null
    private var outputStream: OutputStream? = null

    // ========================
    // 实现接口方法
    // ========================

    override fun openPort(port: String, baudRate: Int): Boolean {
        return try {
            // 打开串口(Android 主流串口库)
            serialPort = SerialPort(port, baudRate, 0)
            outputStream = serialPort!!.outputStream
            true
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }

    override fun sendData(data: String) {
        try {
            outputStream?.write(data.toByteArray())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun closePort() {
        try {
            outputStream?.close()
            serialPort?.close()
        } catch (e: Exception) {
        }
    }

    // ========================
    // 页面使用
    // ========================
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_serial)

        // 直接调用自己实现的方法
        openPort("/dev/ttyS0", 9600)
        sendData("Hello Serial")
    }

    override fun onDestroy() {
        super.onDestroy()
        closePort()
    }
}

🔥 你要的效果 100% 实现

kotlin 复制代码
class SerialActivity : AppCompatActivity(), ISerialPort {
    // 页面自己实现串口方法
    // 页面自己调用串口方法
}

这种写法叫:

接口实现模式 + 页面接口下沉

Activity 直接实现串口标准 → 自己实现 → 自己调用


✅ 优点

  1. 最简单,没有任何多余封装
  2. 直观,串口逻辑全在页面里
  3. 完全符合你想要的结构
  4. 原生安卓最常用的基础封装

相关推荐
煎饼学大模型2 小时前
Agent 的“大脑-手“解耦架构:当推理层和工具执行层各自独立演进
数据库·人工智能·oracle·架构·agent
xingxiliang3 小时前
深入浅出 Android CTS 视频测试:从环境搭建、用例设计到底层通信原理
android·音视频
我命由我123453 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
雨白5 小时前
深入理解 Kotlin 协程 (八):拾遗补阙,探秘官方框架的调度细节与取消闭环
android·kotlin
海天鹰6 小时前
PHP上传文件
android·开发语言·php
2501_915918417 小时前
详解iOS App上架至App Store的全流程步骤与注意事项
android·macos·ios·小程序·uni-app·cocoa·iphone
韩楚风8 小时前
【参天引擎】一次宕机后的数据恢复,让我把 Cantian 持久化与恢复的六大机制全搞明白了
服务器·网络·数据库·分布式·mysql·架构·cantian
Slice_cy9 小时前
Mint 自研框架设计与实现:从重复开发走向配置驱动(五)
前端·后端·架构
heimeiyingwang9 小时前
【架构实战】Helm Chart 进阶:依赖管理、测试与 CI/CD 集成
ci/cd·架构
四眼肥鱼9 小时前
【Nextjs】macos 系统运行报错:Error: Cannot find module '../lightningcss.darwin-x64.node'
前端·架构·前端框架