线程只运行一次 - Java - Android

时间:2017-11-24 21:20:33

标签: java android multithreading bluetooth

所以我正在做一个项目。我有一个Arduino机器人通过蓝牙与应用程序通信。基本上Arduino是一个配备各种传感器的战斗机器人。当机器人识别出它已被拍摄时(通过IR代码)。它向应用程序发送消息,以便可以减少其运行状况。 (Arduino发送小写'h',用'#'作为分隔符来表示消息的结束。现在我正在尝试运行一个线程来监听数据和一个字符('h')或任何其他在处理它的应用程序上收到字符并调用正确的函数。现在我的问题是我的函数只能被调用一次。我是线程的新手并且很难理解它为什么不恢复线程和继续倾听更多角色。

这是监听数据的线程。它有点乱,因为我有一些示踪剂代码试图找到问题

void beginListenForData(){
    final Handler handler = new Handler();
    final Handler handler2 = new Handler();
    final byte delimiter = 35; //ASCII for #
    stopWorker = false;
    readBufferPosition = 0;
    readBuffer = new byte[1024];
    workerThread = new Thread(new Runnable(){

        public void run(){

            while(!Thread.currentThread().isInterrupted() && !stopWorker){

                try{
                    int bytesAvailable = mmInputStream.available();
                    //InputStream mmInputStream = btSocket.getInputStream();
                    //inTest.setText("INPUT: " + bytesAvailable);
                    if(bytesAvailable>0){
                        //inTest.setText("Bytes Available");
                        byte[] packetBytes = new byte[bytesAvailable];
                        mmInputStream.read(packetBytes);
                        for(int i=0;i<bytesAvailable;i++)
                        {
                            byte b = packetBytes[i];
                            if(b == delimiter)
                            {
                                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()
                                    {
                                        /*
                                        Possible messages from arduino
                                            r = arduino ready
                                            k = Robot has tilted and is dead
                                            h = robot has been shot
                                        */


                                        inTest.setText("Received: " + data + "\n" +"Times shot: " + timesShot);

                                        if(data.equals("h")){
                                            //workerThread.interrupt();

                                            System.out.println("ROBOT HAS BEEN SHOT");
                                            robo1.takeDamage(10);
                                            System.out.println("ROBOT HAS CALLED DAMAGE METHOD");
                                        }

                                        //if(data.equals("k")){
                                        //  msg("ROBOT FLIPPED!");
                                        //}


                                    }

                                });
                            }
                            else
                            {
                                readBuffer[readBufferPosition++] = b;
                            }
                        }
                    }
                }
                catch (IOException ex)
                {
                    msg("IEXCEPTION TRIGGER");
                    stopWorker = true;
                }
            }
        }
    });
    msg("WorkerThread Start");
    workerThread.start();
}

此处还有我的takeDamage方法,其中还包含一些示踪代码,并显示了我尝试解决此问题的一些内容。

       private void takeDamage(int dmg){
        ROBOT_HEALTH -= dmg;
        msg("Robot Shot");
        timesShot++;
        System.out.println("ROBOT IS TAKING DAMAGE");
        inTest.setText("Times shot: " + timesShot + "\n Robot Health: " +  ROBOT_HEALTH);

        //workerThread.start();
        //msg("Robot Health" + robo1.getHealth() + "\n");
        //if(this.getHealth() <= 0){
         //   //GAME OVER ROBOT DEAD
          //  Toast.makeText(getApplicationContext(), "ROBOT DEAD",
          //          Toast.LENGTH_LONG).show();
        //}
    }

TLDR;为什么线程在方法调用后不会继续侦听数据。如果没有调用方法,那么处理程序将无限期地循环。

1 个答案:

答案 0 :(得分:0)

我没有真正尝试这个代码,但我认为你明白了。使用start()启动线程,然后使用stop()中断它。 Runnable实现了一个可能永远运行的while循环;)但我猜你想在某个时候停止它。希望这可以帮助!

private Thread thread;    

public void start() {
    if (thread != null) return;
    thread = new Thread(new ListenerRunnable());
    thread.start();
}

public void stop() {
    if (thread == null) return;
    thread.interrupt();
    thread = null;
}

private static class ListenerRunnable implements Runnable {

    @Override
    public void run() {
        while (true) {
            try {

                // !!! Here goes your code to listen !!!

            } catch (final InterruptedException e) {
                if (Thread.currentThread().isInterrupted()) {
                    break;
                }
            }
        }
    }
}