gpt4 book ai didi

android 从 UIThread 获取数据

转载 作者:太空宇宙 更新时间:2023-11-03 12:37:42 24 4
gpt4 key购买 nike

我正在尝试使用 Bluetooth 将 android 数据发送到 arduino .My gui 包含一个 SeekBar和加速度计读数。所有Sockets已成功形成,如果我将数据写入 OutputStream,一切正常的 Socket来自 onSeekBarChanged()方法,以便在我更改 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当前值。所以我试着写信给OutputStreamSocket来自 onSensorChanged(SensorEvent event)加速度计的方法。 Result:Program not responding.

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 来说过载了.我想我应该创建一个new Threadrun() 中无限循环连续发送数据的方法。如何将加速度计和 SeekBar 数据连续发送到这个新线程。

或者我应该从这个新线程收集 UIThread 的加速度计和 SeekBar 的数据。

In Short, how do I get data from UIThread to this new Thread.

请提供您所知道的所有可能的解决方案,以解决我的问题以及我当前程序的任何并发症。

最佳答案

一个很好的方法是使用内置的 Looper类(class)。 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);
}
}

这为您提供了一个单一的后台线程,它可以尽可能快地处理消息,并且您可以从任何其他线程以线程安全的方式提交消息。它们是按顺序处理的。

完成后您需要注意正确关闭循环线程,并确保它可以处理丢失的套接字连接。

如果您需要将其限制为每秒特定的消息速率,事情就会变得有点复杂。 OutputStream.write 是一个阻塞操作,所以为了方便起见我把它去掉了。您要做的是注册您上次在实例字段中处理消息的 System.nanoTime(),并在 handleMessage() 方法中,每当下一条消息在足够的时间过去之前到达时,您计算在处理消息之前必须等待多长时间。这比使用 sendMessageDelayed() 在“提交”端处理它要容易得多。

关于android 从 UIThread 获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14919243/

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