2016-05-26 11 views
0

Ich entwickle eine App, die Wifi/Tcp-Verbindung verwendet, um mit einem Roboter zu kommunizieren. Im Moment benutze ich einen einzigen Thread, um die TCP-Verbindung mit einer TcpClient-Klasse zu verwalten und eine "ConnectTask extends AsyncTask" in meiner MainActivity.Verwendung von Handler in AsyncTask

Bisher ist es das, was ich habe:

TcpClient.java

private OnMessageReceived mMessageListener = null; 

private int bufferSize = 5000; 
public ByteBuffer bf; 
private BufferedInputStream inFromServer; 
private BufferedOutputStream outFromClient; 
. 
. 
. 
public void run() { 

    mRun = true; 
    try { 
     //here you must put your computer's IP address. 
     InetAddress serverAddr = InetAddress.getByName(SERVER_IP); 

     Log.e("TCP Client", "C: Connecting..."); 

     //create a socket to make the connection with the server 
     Socket socket = new Socket(serverAddr, SERVER_PORT); 

     try { 
      Log.i("Debug", "inside try catch"); 

      //receives the message which the server sends back 

      inFromServer = new BufferedInputStream(socket.getInputStream()); 
      outFromClient = new BufferedOutputStream(socket.getOutputStream()); 


      bf = ByteBuffer.allocate(bufferSize); 




      while (mRun) { 
       // Log.i("Debug", "inside while mRun"); 

       bf.order(ByteOrder.LITTLE_ENDIAN); 
       for (int i=0;i<5000;i++) { 
        int b = inFromServer.read(); 

        if (b == -1) { 
         break; 
        } 

        bf.put((byte) b); 

       } 

       if (bf != null && mMessageListener != null) { 
        //call the method messageReceived from MyActivity class 
        // Log.i("Debug","Message received !"); 
        mMessageListener.messageReceived(bf); 
        mMessageListener.updateBatteryLvl(); 
       } 
       bf.position(0); 
      } 
     } 
. 
. 
. 

Und das ist mein ConnectTask in MainActivity:

public class ConnectTask extends AsyncTask<Void, ByteBuffer, TcpClient> { 

    @Override 
    protected TcpClient doInBackground(Void... params) { 
     //we create a TCPClient object and 
     mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() { 
      @Override 
      //here the messageReceived method is implemented 
      public void messageReceived(ByteBuffer message) throws IOException { 
       //this method calls the onProgressUpdate 
       byte[] resultat = new byte[4000]; 
       resultat = message.array(); 
       updateBatteryLvl(); 
       message.clear(); 

Ich bin keine Handlers in tcpclient nicht mit oder connecttask, aber ich habe einige Tutorials gesehen, die sie für Tcp Connection benutzen und ich habe mich gefragt, warum benutzen sie es? Ich habe die Verbindung mit dem Roboter bereits getestet und erhalte die Daten, die er sendet, vollkommen in Ordnung. Werden Handler wie Semaphore verwendet, wenn Multithreads zum Beispiel in derselben Datei geschrieben werden?

Antwort

0

Werden Handler wie Semaphore verwendet, wenn Sie Multithreads haben, die in die gleiche Datei für Beispiel schreiben?

Mehr oder weniger, ja. Handler können nur in einem Thread mit einem Looper erstellt werden (Aufruf des Konstruktors) (Hauptthread ist ein Thread mit einem Looper).

Dann können Sie Runnables und Nachrichten veröffentlichen, die (irgendwann in der Zukunft) vom Handler ausgeführt werden sollen. Diese runables/messages werden vom hanlder in die Warteschlange gestellt und an den Thread gesendet, den sie erstellt haben. Wenn Sie also Dinge in verschiedenen Threads ablaufen lassen und einige Aktionen ausführen möchten, ohne sich um die Race-Bedingungen zu kümmern (oder diese Aktionen in einem bestimmten Thread ausführen müssen, z. B. wenn Sie die Benutzeroberfläche aktualisieren müssen), können Sie "Operationen" posten "in der Handler, und das ist alles.

In Ihrem Fall, mit der AsyncTask, tut es das gleiche, macht die Arbeit in einem getrennten Thread, und das Ergebnis an den MAIN THREAD Commit. Wenn Sie verschiedene Threads verwalten müssen und das Ergebnis auf Single und nicht auf MAIN THREAD festlegen müssen, müssen Sie einen Handler verwenden. Aber wie Sie beschreiben, was Sie tun, ist es nicht notwendig.

0

Sie können keine lange laufenden Betrieb im UI-Thread (Haupt-Thread) oder Sie erhalten "application not responding" (ANR). Sie müssen also Multithreading verwenden und Android Framework bietet Infrastruktur für eine einfachere Datensynchronisation mit dem Hauptthread (Android UI Toolkit ist nicht Thread-sicher).

kann Ihre Wahl zu Problemen führen, denn:

  • AsyncTask nur für Operationen verwendet werden soll, die nicht wenige Sekunden dauern.

  • AsyncTasks werden seriell auf einem einzelnen Hintergrundthread (von API 11) ausgeführt. So lange laufende Arbeiter können andere blockieren.

  • AsyncTasks respektieren den Lebenszyklus Ihrer Host-Aktivität nicht (Sie können Speicherlecks erhalten).

  • Priorität in der Tötungsliste ist low.

Verwandte Themen