Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何确保线程保存结果后执行?_Android_String_Multithreading_Bluetooth_Arduino - Fatal编程技术网

Android 如何确保线程保存结果后执行?

Android 如何确保线程保存结果后执行?,android,string,multithreading,bluetooth,arduino,Android,String,Multithreading,Bluetooth,Arduino,我正在进行Arduino+Android项目,我正在开发一个Android应用程序,其目的是管理数字PID电机速度控制器,Android应用程序必须发送控制器参数Kp、Ki、Kd和设定速度,另一方面Arduino必须发送当前速度,如果我要求,控制器参数,以同步Android应用程序中的值。 这听起来不错,但我无法使用Arduino自动发送和保存的最后一个字符串。 用于接收数据的代码为: public void beginListenForData() { final Handler ha

我正在进行Arduino+Android项目,我正在开发一个Android应用程序,其目的是管理数字PID电机速度控制器,Android应用程序必须发送控制器参数Kp、Ki、Kd和设定速度,另一方面Arduino必须发送当前速度,如果我要求,控制器参数,以同步Android应用程序中的值。 这听起来不错,但我无法使用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();
}
当Arduino reads进入“写入模式”并仅发送一次字符串时,必须在收到“*”后才能退出此模式。 所有这些都可以工作,但是Toast是在线程保存收到的最后一个字符串之前执行的。如何确保线程保存最后一个字符串后toast的执行?
这对于处理字符串信息至关重要。

编辑:如果要从UI线程启动工作线程,然后将结果发布到UI线程,则异步任务可能是一种方法:

使用异步任务

AsyncTask允许您在用户界面上执行异步工作。它在工作线程中执行阻塞操作,然后在UI线程上发布结果,而不需要您自己处理线程和/或处理程序

要使用它,必须将AsyncTask子类化并实现doInBackground回调方法,该方法在后台线程池中运行。要更新UI,您应该实现onPostExecute,它从doInBackground传递结果并在UI线程中运行,这样您就可以安全地更新UI。然后可以通过从UI线程调用execute来运行任务

例如,可以通过以下方式使用AsyncTask实现前面的示例:

现在UI是安全的,代码更简单,因为它将工作分为应该在工作线程上完成的部分和应该在UI线程上完成的部分


工作线程知道它何时收到最后一个字符串吗?它不知道,但是如果我能“构建”一个特殊的代码。在public void run中可能是这样的:ifdata==SpecialCode?我创建了一个SynchronousQueue队列,当数据变为LoL时,将“receive”值放在队列上。问题是当我使用queue.take时-从onClic函数调用,因为它锁定整个应用程序,包括workerThread阻止queue.putdata;所以这意味着我做错了。我不知道如何使用全局信号量。我该怎么办?@JosephMoreno我错了,我没有意识到UI线程正在等待工作线程的结果-UI线程不应该阻塞,这是接管阻塞队列或获取信号量时会发生的情况。请参阅上面的编辑-AsyncTask更适合您的用例。我不知道如何实现AsyncTask如何确保在收到最后一个字符串后执行此操作,因为我需要按顺序多次使用此指令。此外,字符串信息可以是数值或确认消息。
            sendData("#",true);
            sendData("*",true);
            Toast.makeText(getApplicationContext(), receive, Toast.LENGTH_LONG).show();
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);
    }
}