Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将数据写入UI线程上的BluetoothSocket_Android_Android Bluetooth - Fatal编程技术网

Android 将数据写入UI线程上的BluetoothSocket

Android 将数据写入UI线程上的BluetoothSocket,android,android-bluetooth,Android,Android Bluetooth,我正在查看Google的数据,他们在UI线程上写入BluetoothSocket的OutputStream。对吗?通常,流会阻塞,直到数据发送出去 在我的测试中(使用该应用程序),只要设备足够近,通信就会非常迅速。当他们走得更远时,连接中断了。这是通过蓝牙发送数据的正确方式吗?我的消息大小将减少100-500字节。由于文档没有说明这一点,我做了自己的测试:我尝试发送以下数据量,并测量了写入时间 Old Android 2.3 device Recent Android 5.

我正在查看Google的数据,他们在UI线程上写入
BluetoothSocket
OutputStream
。对吗?通常,流会阻塞,直到数据发送出去


在我的测试中(使用该应用程序),只要设备足够近,通信就会非常迅速。当他们走得更远时,连接中断了。这是通过蓝牙发送数据的正确方式吗?我的消息大小将减少100-500字节。

由于文档没有说明这一点,我做了自己的测试:我尝试发送以下数据量,并测量了写入时间

        Old Android 2.3 device    Recent Android 5.0 device
1kB           12ms                       2ms
4kB         15-20ms                      2ms
64kB        25-35ms                      7ms
128kB       10-17ms                      6ms
256kB     2000-3000ms                   3000ms
因为我将发送少于1kB的数据,所以我将在UI线程上执行。他们在“官方”示例聊天应用程序中也这样做

安卓系统似乎有一些至少128kB的内部缓冲区,因此可以编写短消息,而无需使用后台线程


然而,在另一台设备上读取128kB需要一两秒钟的时间。我使用了4kB的读取缓冲区。当我一个字节一个字节地阅读时,可能需要一分钟。

我也很想知道这一点,因为据我所知,BluetoothChat在UI线程上写入蓝牙数据,就像我发现的所有其他Android蓝牙示例一样——所有这些示例似乎都基于BluetoothChat

我已经按照奥利夫的思路做了更多的测试。使用运行4.4.4的三星T113,我发现写60个字符串通常需要12-14毫秒。然而,也有一些情况下,写入时间要长得多——35-45毫秒。此外,如果要写入的设备没有读取发送给它的消息,则发送设备上的缓冲区最终将被填满,写入操作将无限期地阻塞(请参阅)。出于这些原因,我认为一个编写蓝牙的性能良好的应用程序需要在主线程之外编写

(根据Commonware的马克·墨菲(Mark Murphy)的说法,“主应用程序线程上的所有I/O都是一个坏主意”,而BluetoothChat使用主线程进行编写“可能只是一个bug”。

当然,还有一些具体的细节要考虑。在里面 特别是,您应该使用专用线程来读取 流和写入它。这很重要,因为 read(byte[])和write(byte[])方法正在阻止调用。这个 read(byte[])方法阻塞,直到从 流动write(byte[])方法通常不会阻塞,但它可以 如果远程设备未调用read(字节[]),则阻止流控制 速度足够快,中间缓冲区因此变满。 因此,线程中的主循环应该专用于从 输入流。线程中的单独公共方法可用于 启动对OutputStream的写入


你确定他们是在主(ui)线程上完成的吗?“私有类ConnectedThread扩展线程{”从你的github链接复制当他们走得更远时,连接被断开-这是正常的行为,Android根据RSSI参数自动处理,有时使用握手包。有时它在硬件模块上实现,但在现代设备的驱动程序级别上实现。是的,我确定它在UI线程上。
ConnectedThread.write()
方法是从Send按钮的
onClick
处理程序调用的。我在调试器中检查了这个问题。Oliv是正确的。虽然写入是在ConnectedThread上的方法中执行的,但它不在run()中方法,这将需要使用单独的线程进行写入。感谢您的回答,您已经指出在UI线程上写入/读取是一个错误。即使发送少量数据也不能保护您免受此影响。顺便说一句,我没有完成我的蓝牙应用程序。。。