2011-03-28 2 views
1

Je fais et l'application pour envoyer des données à l'aide de sockets d'un appareil Android à un serveur et à l'envers. J'utilise une classe AsyncTask pour gérer la connexion. Mon problème est qu'à un certain moment dans ma classe d'activité principale, je dois lire à partir du flux d'entrée, par exemple. Et ce qui se passe, c'est que cet extrait de code est exécuté avant que ma classe ConnectionHandler ait établi une connexion socket. Des moyens de résoudre ce problème? Voici le code à ma classe ConnectionHandler:problème dans la synchronisation des threads tout en utilisant AsyncTask, Android

public class ConnectionHandler extends AsyncTask<Void, Void, Void>{ 

public static String serverip = "192.168.1.100"; 
public static int serverport = 7777; 
Socket s; 
public DataInputStream dis = null; 
public DataOutputStream dos = null; 
public int message; 



@Override 
protected Void doInBackground(Void... params) { 

    try { 
     Log.i("AsyncTank", "doInBackgoung: Creating Socket"); 
     s = new Socket("192.168.1.100", 7777); 
    } catch (Exception e) { 
     Log.i("AsyncTank", "doInBackgoung: Cannot create Socket"); 
    } 
    Log.i("AsyncTank", "doInBackgoung: Socket created"); 
    if (s.isConnected()) { 
     try { 
      Log.i("AsyncTank", "doInBackgoung: inside input try"); 
      dis = new DataInputStream(s.getInputStream()); 
      Log.i("AsyncTank", "doInBackgoung: InputStream assigned"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected"); 
      e.printStackTrace(); 
     } 
     try { 
      Log.i("AsyncTank", "doInBackgoung: inside output try"); 
      dos = new DataOutputStream(s.getOutputStream()); 
      Log.i("AsyncTank", "doInBackgoung: OutputStream assigned"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket not connected"); 
      e.printStackTrace(); 
     } 
    } else { 
     Log.i("AsyncTank", "doInBackgoung: Cannot assign Streams, Socket is closed"); 
    } 

    return null; 
} 

public void writeToStream(double lat, double lon) { 
    try { 
      Log.i("AsynkTask", "writeToStream : Writing lat"); 
      dos.writeDouble(lat); 
      dos.flush(); 
     } catch (Exception e) { 
     Log.i("AsynkTask", "writeToStream : Writing failed"); 
    } 
    try { 
      Log.i("AsynkTask", "writeToStream : Writing lon"); 
      dos.writeDouble(lon); 
      dos.flush(); 
     } catch (Exception e) { 
     Log.i("AsynkTask", "writeToStream : Writing failed"); 
    } 
} 

public int readFromStream() { 
    try { 
     if (s.isConnected()) { 
      Log.i("AsynkTask", "readFromStream : Reading message"); 
      message = dis.readInt(); 
     } else { 
      Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed"); 
     } 
    } catch (Exception e) { 
     Log.i("AsynkTask", "readFromStream : Reading failed"); 
    } 
    return message; 
} 

}

+2

Vous devez lire à partir du flux dans la méthode doInBackground après que la connexion a été établie. –

Répondre

2

Eh oui, vous devez faire toutes les opérations de réseau dans le fil ASyncTask. Vous pouvez également faire des choses lorsque la tâche se termine en remplaçant la méthode onPostExecute(). Choses là-dedans fonctionne sur le thread d'interface utilisateur, de sorte que vous pouvez manipuler textviews, mises en page, etc.

Exemple de la façon dont vous pouvez utiliser un AsyncTask d'ouvrir un socket et d'écrire un double à elle:

public class ASyncExample extends Activity { 

    private TextView mTextView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // set stuff up 
     super.onCreate(savedInstanceState); 
    } 

    private class WriteToServer extends AsyncTask<Double, Void, Void> { 

     private final String serverip = "192.168.1.100"; 
     private final int serverport = 7777; 
     Socket s; 
     private DataOutputStream dos = null; 

     @Override 
     protected Void doInBackground(Double... params) { 

      try { 

       // open the stream 
       s = new Socket("192.168.1.100", 7777); 
       dos = new DataOutputStream(s.getOutputStream()); 

       // write the passed double to the stream 
       dos.writeDouble(params[0]); 
       dos.flush(); 

      } catch (Exception e) { 
       Log.i("AsyncTank", "something's gone wrong"); 
      } 

      return null; 
     } 
    } 
} 
+0

alors je devrais faire toutes les affectations dans mon doInBackground() et les choses de "communication" dans onPostExecute() ou au moins la partie de lecture? Comment est-ce que je passerais ce que j'ai lu dans onPostExecute() à ma classe d'activité principale? – Syllkons

+0

Non - l'idée est que tout dans 'doInBackground' se passe dans un autre thread, donc ne ralentit pas votre interface utilisateur. Alors, mettez tout ce que vous pouvez dans cette section. 'onPostExecute' s'exécute sur le thread principal (UI), et vous ne devez l'utiliser que si vous voulez mettre à jour les éléments de l'interface utilisateur lorsque la tâche est terminée. En ce qui concerne la communication avec l'activité principale, le plus simple est de faire de votre sous-classe de 'ASyncTask' une classe intérieure ou votre activité, comme ci-dessus. De cette façon, vous pouvez accéder aux champs de classe comme 'mTextView' dans l'exemple ci-dessus. –

+0

Je pense que je l'ai su, je vais essayer demain et voir ce que je vais arriver, merci un million – Syllkons

Questions connexes