2017-11-24 20 views
0

私はプロジェクトに取り組んでいます。私はBluetoothを介してアプリと通信するArduinoロボットを持っています。本質的にArduinoは、さまざまなセンサーを搭載したバトルボックです。ロボットが撮影されたことを認識すると(IRコードを介して)アプリにメッセージを送信して、その健康を低下させることができます。 (Arduinoは、メッセージの終わりを知らせるための区切り文字として '#'を付けて小文字の 'h'を送信します)今は、スレッドを実行してデータをリッスンしようとしています。私の問題は、私の関数は一度しか呼び出せないということです。スレッドには新しく、なぜスレッドを再開しないのかを理解するのが難しいです。複数の文字をリッスン続ける。ここでスレッドは1回しか実行されません - Java - Android

がデータをリッスンスレッドです。少し汚いその私はいくつかのトレーサーコードを持っているように、問題を試してみて、見つけること

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;メソッド呼び出しの後にスレッドがデータをリッスンし続けるのはなぜですか?メソッドが呼び出されない場合、ハンドラは無期限にループを継続します。

答えて

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

ありがとうございました!それは正しい軌道に乗って、少し物事をクリアする。私はまた、自分のbeginListenForData()メソッドをtakeDamageメソッドで呼び出して、スレッドを再起動しました。私はそれが最も効率的か適切な方法かどうかは分かりませんが、それはうまくいきます! – Seraphiim

+0

@ user3525633喜んで助けになる;) –

関連する問題