【问题标题】:Kotlin readBytes() never completesKotlin readBytes() 永远不会完成
【发布时间】:2018-05-11 11:19:23
【问题描述】:

我只是想通过蓝牙套接字进行读写,但我的 readBytes 调用没有完成。我认为这很简单,但也许我只是使用了错误类型的流或其他东西。截至目前,我的代码只是将少量文本作为字节发送。这是占位符代码,将替换为通过流写入和读取文件的代码。这是我的接收线程:

class ReceiveThread(val inStream:BufferedInputStream):Thread() {

var bytes:ByteArray? = null


override fun run() {
    BluetoothService.log("Begin ${BTS_Constants.THREAD_RECEIVE}")
    BluetoothService.log("preparing to read data")
    name = BTS_Constants.THREAD_RECEIVE

//here is my new code
    inStream.use {
        do{
            count++
            BluetoothService.log("read loop round $count")
            byteList.add(it.read() as Byte)
        }while (it.available()>0)
     }
    BluetoothService.log("data read: ${byteList.get(0) as Char}")
}
}

这是我的发送线程:

class SendThread(val outStream:BufferedOutputStream, val file:File? = null):Thread(){

var bytes:ByteArray? = null

override fun run() {
    BluetoothService.log("Begin : ${BTS_Constants.THREAD_SEND}")
    name = BTS_Constants.THREAD_SEND

    bytes = "hello testing".toByteArray()
    try{
        outStream.use {
            it.write(bytes)
            it.flush()
        }
    }catch (ioe:IOException){

    }

    BluetoothService.log("data sent")
}

}

数据已成功发送,BluetoothService.log("data sent") 调用已到达并显示在运行发送线程的设备的 logcat 中。对于运行接收线程的设备,记录“准备读取数据”消息,但从不记录data read: "$bytes message"

如何完成对 inStream.readBytes() 的调用?

编辑:我收到的新错误消息:

11-27 23:45:29.298 16253-16413/com.example.zemcd.fileblue E/AndroidRuntime: FATAL EXCEPTION: RECEIVE
                                                                        Process: com.example.zemcd.fileblue, PID: 16253
                                                                        java.io.IOException: bt socket closed, read return: -1
                  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:588)
                  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
                  at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
                  at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
                  at com.example.zemcd.fileblue.ReceiveThread.run(BluetoothService.kt:230)

【问题讨论】:

    标签: android sockets stream kotlin bluetooth-socket


    【解决方案1】:

    如果您查看 Kotlin 扩展函数 readBytes 的源代码,您会看到它在 InputStream.read(buffer) > 0 时开始循环。根据documentation

    在输入数据可用、检测到文件结尾或引发异常之前,此方法会一直阻塞。

    此循环的第二次迭代冻结您的程序。 所以不要使用方法readBytes。只需read(buffer)。 例如 - https://developer.android.com/guide/topics/connectivity/bluetooth.html#ManagingAConnection

    更新:

    现在ReceiveThread 可以从流中接收一条消息。但是您的蓝牙插座已关闭。所以你的问题在于设置蓝牙连接和inStream的初始化。也许你也有错误的发送部分。

    【讨论】:

    • 谢谢。这个答案非常有用,但是我对代码进行了更改,但它仍然是阻塞的。也许我误会了。我将 bytes = it.readBytes() 更改为 byteSize = it.read(buffer) 并在我的代码中添加了一个 byteSize 变量。作为我的接收线程的一个 Int 字段。我需要做更多的事情吗?我在文档中看不到任何内容,因为我使用的是 kotlin,所以我无法执行while((byteSize = it.read(buffer))!=-1) 循环。
    • @Mox_z 你确定 ReceiveThread 调用方法在 SendThread 调用方法写入之前读取?
    • 是的,写入端正在完成发送。但这可能与它是 BufferedInputStream 有关吗?那里使用了不同的技术吗?
    • 见上面的评论
    • @Mox_z 为什么不能使用while?会不会是蓝牙连接问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    相关资源
    最近更新 更多