在UI线程上将数据写入BluetoothSocket

问题描述 投票:4回答:3

我正在查看谷歌的Bluetooth Chat sample application,他们在UI线程上写信给BluetoothSocketOutputStream。那是对的吗?通常,流阻塞直到数据被发送出去。

在我的测试中(使用该应用程序),只要设备足够接近,通信就会提示。当他们走得更远时,连接被丢弃了。这是通过蓝牙发送数据的正确方法吗?我的邮件大小将为100-500字节。

android android-bluetooth
3个回答
2
投票

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

我按照那些奥利夫的做法做了一些测试。使用运行4.4.4的Samsung T113,我发现写入60个字符串时,写入通常需要12-14ms。但是,也有一些情况下写入时间更长--35-45ms。此外,如果被写入的设备没有读取发送给它的消息,则最终发送设备上的缓冲区将填满,写操作将无限期地阻塞(参见Android BluetoothSocket OutputStream write blocks infinitely)。出于这些原因,我认为编写蓝牙的性能良好的应用程序需要在主线程中执行此操作。

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


2
投票

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

        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线程上进行。他们在“官方”示例聊天应用程序中也这样做。

似乎Android有一些至少128kB的内部缓冲区,因此可以编写短消息而不必用后台线程来打扰自己。

但是,读取128kB在另一台设备上花费了第二或第二。我用过4kB读缓冲区。当我逐字节读取时,可能是一分钟。


1
投票

https://developer.android.com/guide/topics/connectivity/bluetooth#ManageAConnection

当然,有一些实施细节需要考虑。特别是,您应该使用专用线程从流中读取并写入它。这很重要,因为read(byte [])和write(byte [])方法都是阻塞调用。 read(byte [])方法将阻塞,直到从流中读取内容。 write(byte [])方法通常不会阻塞,但如果远程设备没有足够快地调用read(byte [])并且中间缓冲区因此变满,它可以阻止流控制。因此,线程中的主循环应专用于从InputStream读取。线程中的单独公共方法可用于启动对OutputStream的写入。

© www.soinside.com 2019 - 2024. All rights reserved.