2017-11-24 1 views
0

Also arbeite ich an einem Projekt. Ich habe einen Arduino-Roboter, der über Bluetooth mit einer App kommuniziert. Im Wesentlichen ist der Arduino ein Kampfroboter, der mit verschiedenen Sensoren ausgestattet ist. Wenn der Roboter erkennt, dass er aufgenommen wurde (über IR-Codes). Er sendet eine Nachricht an die App, damit der Status verringert werden kann. (Arduino sendet Kleinbuchstaben 'h' mit einem '#' als Trennzeichen, um das Ende der Nachricht zu signalisieren. Jetzt versuche ich einen Thread auszuführen, um auf die Daten und auf ein Zeichen ('h') oder irgendein anderes Zeichen zu warten Charakter ist in der App erhalten, die es behandelt wird und die richtige Funktion aufgerufen wird. Jetzt ist mein Problem, dass meine Funktion nur einmal aufgerufen werden kann. Ich bin neu in Threads und es ist schwer zu verstehen, warum es den Thread nicht fortgesetzt und weiterhin für mehr Zeichen zu hören.Thread läuft nur einmal - Java - Android

hier ist der Thread für die Daten hören. Es ist ein wenig chaotisch, wie ich einige Tracer-Code haben, um zu versuchen und die Frage

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(); 
} 

auch hier ist meine takeDamage Methode, die auch zu finden hat etwas Tracer-Code drin und zeigt einige o Ich habe versucht, das Problem zu lösen.

 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; Warum hört der Thread nach einem Methodenaufruf nicht weiter auf Daten zu? Wenn keine Methode aufgerufen wird, wird der Handler unbegrenzt weiterlaufen.

Antwort

0

Ich habe diesen Code nicht wirklich versucht, aber ich denke, Sie bekommen die Idee. Mit start() starten Sie den Thread und mit stop() unterbrechen Sie es. Die Runnable implementiert eine while-Schleife, die möglicherweise für immer laufen kann;) Aber ich denke du wirst es irgendwann stoppen. Hoffe das hilft!

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; 
       } 
      } 
     } 
    } 
} 
+0

Vielen Dank! Das hat mich auf die richtige Spur gebracht und die Dinge ein wenig geklärt. Ich habe gerade meine Methode beginListenForData() in der takeDamage-Methode aufgerufen, die auch den Thread neu startet. Ich bin mir nicht sicher, ob es der effizienteste oder richtigste Weg ist, aber es funktioniert! – Seraphiim

+0

@ user3525633 glücklich, um Hilfe zu sein;) –