我正在尝试使用蓝牙将android数据发送到arduino.我的gui包含一个Seekbar和加速度计读数.所有套接字都成功形成,如果我从onSeekbarChanged()方法将数据写入Socket的OutputStream,那么每件事都能正常工作每当我更改Seekbar时,数据都将传输到arduino.
public voID onProgressChanged(Seekbar seekbar, int progress, boolean fromUser) { if(seekbar.getID() == R.ID.seekbar) { speed.setText(String.valueOf(progress)); String outputData = String.valueOf(progress)+","; try { streams.write(outputData.getBytes());//writes data to OutputStream of Socket }catch (Exception e){ Log.d("RTR","Sockets not yet formed"); } } }
问题是我需要连续发送Accelerometer数据和Seekbar当前值.所以我试图从加速计的onSensorChanged(SensorEvent事件)方法写入Socket的OutputStream.结果:程序没有响应.
public voID onSensorChanged(SensorEvent event) { if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { float accXYZ[] = event.values; float accX = accXYZ[0]; float accY = accXYZ[1]; float accZ = accXYZ[2]; x.setText(String.format("%.2f",accX)); y.setText(String.format("%.2f",accY)); z.setText(String.format("%.2f",accZ)); String outputData = x.getText().toString()+","+speed.getText().toString()+";"; try{ streams.write(outputData.getBytes()); }catch (Exception e){ //Log.d("RTR","X"); } } }
我知道这在UI Thread上有太多的重载.我想我应该在run()方法中创建一个带有无限循环的新线程来连续发送数据.我怎么能连续地将加速度计和Seekbar数据发送到这个新线程.
或者我应该从这个新线程收集UIThread的加速度计和Seekbar的数据.
In Short, how do I get data from UIThread to this new Thread.
请提供您对我的问题所了解的所有可能解决方案以及我当前程序的任何并发症.
解决方法:
一个很好的方法是使用内置的Looper
类. Looper是支持AndroID UI线程的消息排队系统,您也可以将它与您自己的线程一起使用.它的设计方式有什么好处,它创建了非常少的垃圾收集负载(取决于你使用的参数类型,它可以是没有).
我正在写这个写意,所以你不得不破解它以使其工作,但这里最终看起来像:
class LooperThread extends Thread { private static final int MSG_TYPE_OUTPUT_DATA = 0; private Handler mHandler; private volatile OutputStream mOutputStream; public voID run() { Looper.prepare(); mHandler = new Handler() { public voID handleMessage(Message msg) { if (msg.what == MSG_TYPE_OUTPUT_DATA && mOutputStream != null) { //try-catch left out for brevity mOutputStream.write(msg.obj.getBytes()); } } }; Looper.loop(); } public voID submitReading(String outputData) { mHandler.sendMessage(mHandler.obtainMessage(MSG_TYPE_OUTPUT_DATA, outputData); }}
您的设置代码将执行以下 *** 作:
private voID setup() { Socket sock = setupBluetoothConnection(); this.looperThread = new LooperThread(); this.looperThread.setoutputStream(sock.getoutputStream()); this.looperThread.start();}
最后,传感器事件处理程序:
public voID onSensorChanged(SensorEvent event) { if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // snip... String outputData = x.getText().toString()+","+speed.getText().toString()+";"; this.looperThread.submitReading(outputData); }}
这给你的是一个后台线程,它尽可能快地处理消息,并且你可以从任何其他线程以线程安全的方式提交消息.它们按顺序处理.
完成后,您需要注意正确关闭looper线程,并确保它可以处理套接字连接丢失.
如果你需要将其限制为每秒一定的消息速率,事情会变得复杂一些. OutputStream.write是一个阻塞 *** 作,所以为了方便,我把它留了下来.你要做的是注册你最后在实例字段中处理消息的System.nanoTime(),并在handleMessage()方法内,每当下一条消息进来之前,经过足够的时间,你计算你有多长时间等待才能处理消息.这比使用sendMessageDelayed()在“提交”端处理它要容易得多.
总结以上是内存溢出为你收集整理的android从UIThread获取数据全部内容,希望文章能够帮你解决android从UIThread获取数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)