我正在开发一个项目Arduino + Android,我正在开发一款Android App,其目的是管理数字PID电机速度控制器,Android App必须发送控制器参数(Kp,Ki,Kd)另一方面,Arduino必须发送当前速度,如果我请求,还必须发送控制器参数,以便同步Android App中的值。 这听起来不错,但我不能自动使用Arduino发送(并保存)的最后一个字符串。 用于接收数据的代码是:
public void beginListenForData()
{
final Handler handler = new Handler();
pauseSerialWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
try { inStream = btSocket.getInputStream(); }catch (IOException e){}
Thread workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !pauseSerialWorker)
{
try
{
int bytesAvailable = inStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
inStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == lineDelimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
textView.setText(data);
receive=data;
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
pauseSerialWorker = true;
}
}
}
});
workerThread.start();
}
此主题显示收到的最后一个字符串(因为它在textview中显示),并将其保存在&#39; receive&#39; (一个公共全局String),这个开始基本上进入app初始化。 我使用此代码来征求数据并将其显示为Toast。
sendData("#",true);
sendData("*",true);
Toast.makeText(getApplicationContext(), receive, Toast.LENGTH_LONG).show();
当Arduino读到&#39;#&#39;进入“写入”模式&#39;并且必须收到&#39; *&#39;之后只发送一次字符串退出此模式。 一切正常,但Toast在Thread保存收到的最后一个字符串之前执行。在线程保存最后一个字符串后,如何确保toast的执行? 这对于处理字符串的信息至关重要。
答案 0 :(得分:0)
编辑:如果您从UI线程启动工作线程,然后将结果发布到UI线程,那么AsyncTask
可能是要走的路。 According to the documentation:
使用AsyncTask
AsyncTask
允许您在用户界面上执行异步工作。它在工作线程中执行阻塞操作,然后在UI线程上发布结果,而不需要您自己处理线程和/或处理程序。要使用它,您必须继承
AsyncTask
并实现doInBackground()
回调方法,该方法在后台线程池中运行。要更新UI,您应该实现onPostExecute()
,它从doInBackground()
提供结果并在UI线程中运行,因此您可以安全地更新UI。然后,您可以通过从UI线程调用execute()
来运行任务。例如,您可以通过以下方式使用AsyncTask实现上一个示例:
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
现在UI是安全的,代码更简单,因为它将工作分为应该在工作线程上完成的部分以及应该在UI线程上完成的部分。