关于蓝牙开发之数据缓存问题(脏数据)
2015-10-05 20:15
393 查看
想想已经接触蓝牙两个多月了,这期间真是遇到了各种问题。因为我的是做Android手机与开发板中的蓝牙2.0相互通信,所以关于Google的Android设备之间的相互通信基本上是用不到。所以得自己摸索,其中最大的一个就是自动连接开发主板上的蓝牙设备,过程比较复杂有兴趣的朋友可以了解一下关于Android蓝牙的三种连接方式,这里就不做介绍了。接下来介绍的是蓝牙连接之后的数据处理问题。
我们都知道,蓝牙连接成功后可以得到一个套接字,然后可以在套接字中获取一个输出流,然后可以从输出流中得到想要的数据。大概流程就是:
当然,上面的过程没有什么问题。
然而在实际的应用中,上述方法可能不太适合了。考虑到高效性,不能一个字节一个字节的read(),这样效率会降低。所以升级一下read的方式,如下:
下面以图片说明:
红色的代表写入进程,绿色表示读取进程;假设写入线程速度比读取线程速度要快,这将可能会导致一个结果,当数据还没有读取完,又开始写入数据,这将会导致出现脏数据。为什么会出现这样的问题,那是因为两个操作(读写)都是在同一个buffer上进行。好了,到这还没有能完全解释这个问题。那么问题出现在哪里呢?
我们发现这个read(buffer) 方法并没有返回值,按理说应该返回一值才对啊。这就是Java的读取数据的机制问题了。这个read(buffer)并没有一个返回值,而是从传入的参数buffer经过read(buffer) 方法之后直接拿到。 也就是说读写都在同一个buffer上,而这read和write方法并不保证线程安全问题,所以会出现脏数据!
好了,知道“病根”那就应该对症下药了,其中一个解决的方案就是将这个buffer拷贝一份然后在做处理。详细步骤有待完善,需要的朋友请留言我会尽快更新。
(本文将持续更新)
我们都知道,蓝牙连接成功后可以得到一个套接字,然后可以在套接字中获取一个输出流,然后可以从输出流中得到想要的数据。大概流程就是:
<span style="font-size:24px;"><pre name="code" class="java"> socket.connect();//得到一个套接字 try { mmInStream = socket.getInputStream(); //获取一个输入流 mmOutStream = socket.getOutputStream();//获取一个输出流 mSocket = socket; } catch (IOException e) { e.printStackTrace(); }</span>intData = mmInStream.read();//对数据进行读取
当然,上面的过程没有什么问题。
然而在实际的应用中,上述方法可能不太适合了。考虑到高效性,不能一个字节一个字节的read(),这样效率会降低。所以升级一下read的方式,如下:
<span style="font-size:24px;">byte[] <span style="color:#ff0000;">buffer</span>=new byte[64] ; while(ture){ <span style="color:#ff0000;background-color: rgb(204, 204, 204);">read(buffer) ;</span> //处理buffer数据 <span style="color:#ff0000;">BThread.deal(buffer);/</span>/这个是在另外的一个线程来进行数据处理 }</span>这看起来似乎没有什么问题,好像也正确,正常流程不就这样吗;但是请注意了,这个地方涉及到了两个线程之间的同步问题了还有一个最重要的问题,就是这个buffer缓存的问题。
下面以图片说明:
红色的代表写入进程,绿色表示读取进程;假设写入线程速度比读取线程速度要快,这将可能会导致一个结果,当数据还没有读取完,又开始写入数据,这将会导致出现脏数据。为什么会出现这样的问题,那是因为两个操作(读写)都是在同一个buffer上进行。好了,到这还没有能完全解释这个问题。那么问题出现在哪里呢?
我们发现这个read(buffer) 方法并没有返回值,按理说应该返回一值才对啊。这就是Java的读取数据的机制问题了。这个read(buffer)并没有一个返回值,而是从传入的参数buffer经过read(buffer) 方法之后直接拿到。 也就是说读写都在同一个buffer上,而这read和write方法并不保证线程安全问题,所以会出现脏数据!
好了,知道“病根”那就应该对症下药了,其中一个解决的方案就是将这个buffer拷贝一份然后在做处理。详细步骤有待完善,需要的朋友请留言我会尽快更新。
(本文将持续更新)
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories