2012-12-21 3 views
4

J'ai utilisé la méthode InputStream.read(byte[] b, int off, int len) pour lire les données, mais j'ai maintenant rencontré un problème de délai d'attente. J'attends parfois des délais d'attente de lecture, et je devrais avoir le programme s'ajuster en conséquence après un timeout. J'ai essayé d'implémenter un Thread mais je ne connais vraiment rien à Threads et je n'arrive pas à le faire fonctionner. Je tiens également à ajouter que ce thread est en cours d'initialisation dans un autre thread. Je ne suis pas sûr de ce que les implications de cela sont, mais cela peut causer un problème.Thread pour attraper un BluetoothSocket InputStream.read() timeout

Mon code initial avait fonctionné pour la majorité des fois que je devais lire, mais chaque fois que j'attends un délai d'expiration, mon programme se fige à l'appel read() et ne expire jamais. Lorsque j'ai implémenté ce nouveau code, les heures où mon code initial a fonctionné ont expiré. J'utilise Thread.wait(500) que je suppose être 500 millisecondes, mais je ne trouve pas de Javadocs y compris la fonction wait(). Here et Here. Autres publications liées à: 1, 2, 3.

J'ai également regardé dans la déclaration d'un délai d'attente pour le BluetoothSocket, mais je ne peux pas le trouver n'importe où dans le documentation.

Voici ce que mon code initial ressemble:

public void run(int length) throws IOException { 
     buffer = new byte[1024]; 
     try { 
       bytes = mmInStream.read(buffer, 0, length); 
       mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer) 
         .sendToTarget(); 
     } catch (IOException e) { 
       Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST); 
       Bundle bundle = new Bundle(); 
       bundle.putString(TOAST, "Device has disconnected from the Bluetooth Module."); 
       msg.setData(bundle); 
       mHandler.sendMessage(msg); 
       connectionLost(); 
       BluetoothService.this.start(); 
     } 

C'est ce que j'ai essayé de mettre en œuvre:

public void run(int length) throws IOException { 
     buffer = new byte[1024]; 
     length1 = length; 
     Thread myThread = new Thread(new Runnable() { 
      public void run() { 
       try { 
        bytes = mmInStream.read(buffer, 0, length1); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 

     synchronized (myThread) { 
      myThread.start(); 
      try { 
       myThread.wait(500); 
       if(myThread.isAlive()) { 
        mmInStream.close(); 
        Log.i("InStream", "Timeout exceeded!"); 
       } 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
     try { 
      myThread.run(); 
      mHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer) 
         .sendToTarget(); 
     } catch (IOException e) { 
       Message msg = mHandler.obtainMessage(MainMenu.MESSAGE_TOAST); 
       Bundle bundle = new Bundle(); 
       bundle.putString(TOAST, "Device has disconnected from the Bluetooth Module."); 
       msg.setData(bundle); 
       mHandler.sendMessage(msg); 
       connectionLost(); 
       BluetoothService.this.start(); 
     } 

EDIT:

Je suis en train de recréer

buffer = new byte[1024]; 
bytes = mmInStream.read(buffer, 0, length); 

Je l'ai fait ce qui suit:

Scanner scan = new Scanner(new InputStreamReader(mmInStream)); 
String readIn; 
try { 
    readIn = scan.next(); 
    bytes = 5; // I tried with or without this, since I do not think it matters... 
    buffer = readIn.getBytes(Charset.forName("US-ASCII")); 
} 

plus tard dans mon code que je fais cet appel .... modifier Désolé encore, l'appel buf=read(5) va à ce qui est indiqué ci-dessus.

byte[] buf = buffer; 
write(a); 
buf = read(5); 
Log.i(TAG, "Before buf[5]"); 
try { 
    buf[5] = '\0'; 
} catch(NullPointerException e) { 
    return false; 
} 

Lorsque j'utilise la méthode originale, il passe cette fin d'appel buf[5]. Mais quand j'utilise la nouvelle méthode, cela me donne un IndexOutOfBoundsException à cet endroit. Est-ce que je manque quelque chose? L'entrée attendue doit être

Répondre

4

L'exemple de conversation bluetooth est vraiment médiocre à cet égard, vous devez utiliser un scanner d'entrée au lieu de mmInStream.read. Voici ce que j'utilise et cela fonctionne raisonnablement bien ...

Pour votre cas d'utilisation, vous ignorez tout le tampon et l'octet et écrivez et lisez (inutile d'en utiliser quand vous utilisez un scanner et inputtreamreader comme ceux ce truc pour vous) ... en d'autres termes, le code ci-dessous prend soin de tout cela pour vous. J'ai changé le délimiteur pour vous en CRLF. Qu'est-ce que le code ci-dessous est que vous envoyez une chaîne et il l'écrit et puis lit. Si vous n'avez pas besoin d'envoyer quoi que ce soit à l'appareil distant, commencez simplement par scan = new Scanner. Chaque fois qu'une ligne est lue et se termine par \ r \ n, elle sera stockée dans l'instruction de chaîne.

Donc, si vous voulez envoyer « un », vous écririez

String readIn = beginListenForData("a"); 

L'un sera envoyé sous la mmOutStream, puis le scanner lire la mmInStream et de recueillir tous les personnages, puis une fois qu'il voit un CRLF retournera les caractères lus et les retournera dans votre chaîne readIn. Avoir du sens?

private String beginListenForData(String msg0) { 
    msg0 += "\r"; //this adds a return character to the string, you can omit this if you just send an a and the remote device understands what that means. 
    String instring = ""; 
    try { 
     mmOutStream.write(msg0.getBytes()); 
    } catch (IOException ex) {    
     stop(); 
    } 
    scan = new Scanner(new InputStreamReader(mmInStream)); 
    scan.useDelimiter(Pattern.compile("[\\r\\n]+")); 
    instring = scan.next(); 
    scan = null; 
    return instring; 
} 
+0

Merci, cela ne fonctionne pas encore, mais cela semble être le chemin à parcourir. – JuiCe

+0

@JuiCe que NP, en utilisant le scanner et le lecteur inputtream est vraiment beaucoup plus facile que d'essayer d'implémenter votre propre lecteur tamponné qui ressemble à ce que vous essayez de faire (croyez-moi, été fait cela) ... – logray

+0

J'ai l'impression de le faire fonctionner, j'ai édité mon post si vous pouviez prendre le temps de le vérifier. Merci – JuiCe

Questions connexes