2010-12-05 17 views
9

Android noob ici. J'apprends le meilleur en voyant le code source d'un exemple fonctionnel, mais j'ai été incapable de trouver un exemple simple mais complet d'utilisation d'un socket dans son propre thread.Comment obtenir des données depuis/vers une socket dans un thread?

J'ai un service Android qui doit communiquer avec Internet. Je veux ouvrir un socket TCP qui se connecte à un serveur sur Internet. Le service doit envoyer des données à Internet et les données provenant du réseau doivent être envoyées au service. Puisque le service fait également d'autres choses, la connexion socket doit vivre dans son propre thread.

Toute idée où je pourrais trouver un exemple d'une socket dans un fil avec la communication de/vers le socket?

Merci

enter image description here

Répondre

15

Vous devez simplement créer une tâche asynchrone qui communique en arrière-plan, puis met à jour le thread d'interface utilisateur selon les besoins. Voici le fil d'arrière-plan pour obtenir des informations à partir d'une prise et mettre à jour une vue de texte avec le nombre d'octets qu'il récepteurs

public class InternetTask extends AsyncTask<Void, Integer, Void> { 

    private WeakReference<TextView> mUpdateView; 

    public LoginTask(TextView view) { 
     this.mUpdateView = new WeakReference<TextView>(view); 
    } 

    @Override 
    protected Void doInBackground() { 

     try { 
      Socket socket = new Socket("127.0.0.1", 80); 
        InputStream is = socket.getInputStream(); 

        byte[] buffer = new byte[25]; 
        int read = is.read(buffer); 
        while(read != -1){ 
         publishProgress(read); 
         read = is.read(buffer); 
        } 

        is.close(); 
        socket.close(); 



     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     if(mUpdateView.get() != null && values.length > 0){ 
        mUpdateView.get().setText(values[0].toString()); 
       } 
    } 

} 

Et voici comment vous Botté fil de

public class TestTab extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.someLayout); 

      TextView textView = (TextView)findViewById(R.id.someid); 
      InternetTask task = new InternetTask(textView); 
      task.execute(); 

    } 
} 
+0

Y at-il un façon d'envoyer des données supplémentaires à une asyncTask une fois qu'il a été démarré afin que les données peuvent être envoyées sur le socket? Je vois comment utiliser publishProgress et onProgressUpdate pour obtenir des données à partir du thread d'arrière-plan vers le thread de l'interface utilisateur, mais je ne vois pas comment aller dans l'autre sens pendant que la tâche est en cours d'exécution. –

+2

Vous pouvez définir toutes les autres méthodes de votre tâche asynchrone que vous souhaitez. Sachez simplement que la méthode doInBackground() sera la seule exécutée sur un thread séparé. Vous pouvez également transmettre les données que vous souhaitez envoyer dans le constructeur ou à la méthode execute(). –

+0

Lorsque j'ouvre une socket dans doInBackground(), ce nouveau thread va bloquer jusqu'à ce que les données arrivent sur le socket. Lorsque les données arrivent, je peux l'envoyer au thread de l'interface utilisateur via publishProgress. Étant donné que le socket a été créé sur ce thread de travail, comment puis-je envoyer des données au socket à partir du thread de l'interface utilisateur? J'ai affaire à un flux de données, donc envoyer des paramètres avec la commande execute() est bon, mais j'ai besoin d'envoyer continuellement des données au socket. –

8

Voici un blog à long sur ce sujet, où les deux parties serveur et client montrent, avec la communication socket va sur un thread séparé.

http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/

Une chose à prendre en compte est que si vous passez int s vous pouvez rencontrer un problème d'ordre d'octet, donc, juste faire quelques tests et je vous suggère que le serveur envoie le format dont Android a besoin, au cas où vous auriez des serveurs sur plus d'un système d'exploitation.

Pour une façon simple, sur l'Android pour trouver l'ordre des octets, vous pouvez utiliser ceci: http://developer.android.com/reference/java/nio/ByteOrder.html

Selon cet article, l'ordre des octets peut être échangé pour l'optimisation: http://en.wikipedia.org/wiki/Dalvik_(software)

+0

C'est la plus claire code que j'ai vu en montrant comment créer des sockets. Toutefois, alors que l'exemple de serveur montre comment renvoyer des données au thread d'interface utilisateur (via le gestionnaire), aucun des exemples ne montre comment déplacer des données du thread d'interface utilisateur vers le thread de socket. –

+0

Vous pouvez utiliser View.post pour revenir au thread d'interface utilisateur, mais cette page peut vous aider d'autres façons: http://developer.android.com/guide/appendix/faq/commontasks.html#threading –