将带有后台任务的功能从主 activity 移动到它自己单独的 class

Moving functionalty with background tasks from main activity into it's own separate class

在我的 kotlin 应用程序中,我想将所有与蓝牙相关的功能移到它自己的 class 中。 虽然我很清楚如何将方法移动到单独的 class,但我不清楚如何将方法移动到 class 以在后台更新数据。

蓝牙class在后台接收到一些数据后如何触发主activity(目前是协程运行读取循环) 例如,这里是读取传入蓝牙数据的函数。它工作正常但直接更新 UI:

private suspend fun readBT() {
    val buffer = ByteArray(1024)
    var receivedSoFar = ""

    /* Keep listening to the InputStream until an exception occurs or cancel is set. */
    while (state == "connected") {
        try {
            /* nrOfBytes will hold the number of bytes in the buffer */
            val nrOfBytes = inStream?.read(buffer)
            /*  add buffer content to current line */
            receivedSoFar += String(buffer, 0, nrOfBytes!!)
            /* until (incl) newline character */
            if (receivedSoFar.contains("\n")) {
                withContext(Dispatchers.Main) { txt_state.text = (receivedSoFar.dropLast(1)) }
                receivedSoFar = ""
            }
        } catch (e: Exception) {
            if (state == "connected") {
                withContext(Dispatchers.Main) { txt_state.text = "error while reading bt data from Wallie" }
                state = "error_during_read"
            }
        }
    }
}

您的 MainActivity 和新的 BluetoothClass 应该通过回调进行通信。回调可以是 BluetoothClass' 构造函数的参数:

class BluetoothClass(
  private val updateText: (String) -> Unit,
  ...
)

MainActivity 将在实例化 BluetoothClass 时传入该 lambda 的实现:

bluetoothClass = BluetoothClass(updateText = { text -> txt_state.text = text })

最后,BluetoothClass 应该在需要更新文本时调用 lambda:

if (receivedSoFar.contains("\n")) {
  withContext(Dispatchers.Main) { updateText(receivedSoFar.dropLast(1)) }
  receivedSoFar = ""
}