gpt4 book ai didi

处理程序消息数据被下一条消息覆盖的 Java 线程问题

转载 作者:搜寻专家 更新时间:2023-11-01 09:13:30 25 4
gpt4 key购买 nike

我有一个从蓝牙流读取数据的线程,该线程在数据进入时将数据发送到主 UIThread 上的处理程序(基于 Bluetooth Chat Sample )。

我发现了一个经常出现的线程问题。首先,一些代码供引用。

BluetoothService.java(只是读取传入数据流的部分。在这段代码运行之前已经正确设置)

public void run() {
DebugLog.i("BluetoothService", "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);

DebugLog.d("BluetoothService", new String(buffer, 0, bytes));
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
DebugLog.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}

在我的主要 Activity 中定义的处理程序(部分):

// The Handler that gets information back from the BluetoothService
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothService.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
DebugLog.d("BluetoothHandler", readMessage);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;

}
}
};

当一个小的、连续的数据流进入 mmInStream 时,我的问题就来了。例如,“abcd”。如果一次读取“abcd”,则此代码正常运行并且日志显示为:

BluetoothService: BEGIN mConnectedThread
BluetoothService: abcd
BluetoothHandler: abcd

但是如果连续的数据 block 被分成两部分读取,则第二组数据在到达处理程序时会覆盖第一组数据。这是我见过的一些示例日志。

BluetoothService: BEGIN mConnectedThread
BluetoothService: a
BluetoothService: bcd
BluetoothHandler: b
BluetoothHandler: bcd

或者:

BluetoothService: BEGIN mConnectedThread
BluetoothService: abc
BluetoothService: d
BluetoothHandler: dbc
BluetoothHandler: d

或者:

BluetoothService: BEGIN mConnectedThread
BluetoothService: ab
BluetoothService: cde
BluetoothHandler: cd
BluetoothHandler: cde

请注意,发送的第二条消息总是会覆盖第一条消息的数据,并且只会覆盖最短消息的长度。此外,两条消息总是在第一条消息被 mHandler 处理之前发送。

我猜我是某个地方的公共(public)缓冲区,在第一条消息完全处理之前被覆盖了,但我看不到在哪里。有什么建议吗?

最佳答案

是否有可能在创建消息对象时必须使用第二个字节缓冲区?

mHandler.obtainMessage(MESSAGE_READ, bytes, -1, copyOfBuffer)

我怀疑 mHandler(尽管我不知道它是什么)保留对您发送给他的那个字节数组的引用。

关于处理程序消息数据被下一条消息覆盖的 Java 线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6417945/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com