代码之家  ›  专栏  ›  技术社区  ›  Seraphiim

线程只运行一次-Java-Android

  •  0
  • Seraphiim  · 技术社区  · 8 年前

    所以我在做一个项目。我有一个Arduino机器人,可以通过蓝牙与应用程序通信。从本质上讲,Arduino是一种配备各种传感器的战斗机器人。当机器人识别出它被射杀时(通过红外代码)。它会向应用程序发送一条消息,以降低其运行状况。(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();
            //}
        }
    

    太长,读不下去了为什么线程在方法调用后不继续侦听数据。如果没有调用方法,则处理程序将无限期地保持循环。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Peppermint Paddy    8 年前

    我没有真正尝试过这个代码,但我认为你明白了。具有 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;
                    }
                }
            }
        }
    }