Android将延迟发送的ArrayList命令发送到OBD

时间:2017-05-25 15:33:32

标签: java android delay obd-ii

我需要向OBD端口发送一个命令列表,因为ELM327无法一起管理所有命令......

我尝试使用此代码但无法正常工作

public void repeatCommand(){


        for (final String command : commandArray){

            Log.d(TAG, "Giro for");

            final Handler handlerTimed = new Handler();
            handlerTimed.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //Do something after 100ms
                    sendMessage(command);
                }
            }, 1000);


        }

        /*String message = "010C\r";
        sendMessage(message);*/
    }

它仅在1秒后发送第一个命令,但另一个命令发出nope。 如何发送延迟的所有命令让写入管理发送到OBD的所有命令?

好的,我使用建议的方法发送第一个命令并等待响应....当得到响应时,发送下一条消息。

 private synchronized void manage(BluetoothSocket socket, BluetoothDevice
            device) {
        Log.d(TAG, "connected, Socket Type:");

        // Cancel the thread that completed the connection
        if (mConnectThread != null) {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        // Cancel any thread currently managing connections
        if (mManageThread != null) {
            mManageThread.cancel();
            mManageThread = null;
        }

        // Start the thread to manage the connection and perform transmissions
        mManageThread = new ManageDataThread(socket);
        mManageThread.start();

        // Send the name of the connected device back to the UI Activity
        Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
        Bundle bundle = new Bundle();
        bundle.putString(Constants.DEVICE_NAME, device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);
        // Update UI title
        updateUserInterfaceTitle();
    }

这里是管理连接的线程..

  public class ManageDataThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private boolean wait_response = false;

        public ManageDataThread(BluetoothSocket socket) {
            Log.d(TAG, "create ManageDataThread: ");

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "temp sockets not created", e);
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
            mState = STATE_CONNECTED;

        }

        public void run() {

            while(true) {
                for (final String command : commandArray) {

                    byte[] send = command.getBytes();
                    write(send);
                    //mState = STATE_WAIT_RESPONSE;

                    byte[] buffer = new byte[1024];
                    int bytes;

                    // Keep listening to the InputStream while connected
                    while (wait_response) {
                        try {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);

                            //TODO devo gestire l'arrivo di bytes
                            ObdCommand obc = new ObdCommand();
                            obc.readResult(mmInStream);

                            formattedMessage = obc.getResult();
                            //buffer = (byte) obc.getBuffer();

                            // Send the obtained bytes to the UI Activity
                            mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
                                    .sendToTarget();

                            wait_response = false;

                        } catch (IOException e) {
                            Log.e(TAG, "disconnected", e);
                            connectionLost();
                            break;
                        }
                    }


                }
            }



        }

它有点不完美,但现在它的工作...... 我将打开一个新帖子来停止它并更新命令的数组列表,因为如果我更改命令列表,循环保留旧数组列表,所以我需要通知线程arraylist已更改

修改

不要使用while(true)内部线程,最好在需要停止线程时使用变量设置为True e将变量设置为false,或者在停止线程时出现问题....

2 个答案:

答案 0 :(得分:1)

要考虑的一件事是,当你创建一个处理程序并且没有为它提供一个looper时,它将使用它的当前线程的looper。 所以我最好的猜测,因为我们没有你的代码,你实际上是在一个不是主要的线程中运行它。确保你的线程在途中不会被杀死,它应该可以工作。

另外,一些编码提示:
首先,我必须说,设置循环的外部会更有效 这样你就不会浪费内存在每次迭代中创建一个处理程序 所以看起来应该是这样的:

public void repeatCommand()
{
    final Handler handlerTimed = new Handler();

    for (final String command : commandArray){

        Log.d(TAG, "Giro for");

        handlerTimed.postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 100ms
                sendMessage(command);
            }
        }, 1000);
    }
}

其次,我强烈建议您设置班级的等级,例如1000的值。

答案 1 :(得分:1)

使用OBD2(一种串行协议)的正确方法是实现类似于命令特定回调的命令队列,这些回调将响应发送给您请求的命令。命令队列应该在后台线程中工作,操作队列并侦听串行端口。甚至不要开始延迟或类似的方法。