web-dev-qa-db-fra.com

Comment utiliser un thread séparé pour effectuer des requêtes http

J'ai une application qui exécute des requêtes HTTP (appelant spécifiquement l'API FogBugz) lorsque l'utilisateur clique sur certains boutons. À l'heure actuelle, je crée simplement un service au démarrage de l'application, puis j'appelle différentes méthodes dans ce service pour terminer les demandes. Cependant, lorsque je fais cela, il y a le blocage habituel dans le thread d'interface utilisateur. J'ai regardé AsyncTask, mais je ne suis pas sûr qu'il fera ce que je veux accomplir. Étant donné que j'ai besoin d'analyser instantanément le XML renvoyé par la demande HTTP, j'ai besoin d'un processus capable de renvoyer ces données au thread d'interface utilisateur. ASyncTask pourra-t-il accomplir cela, ou existe-t-il un autre moyen?

    public static InputStream makeRequest(String httpRequest)
    {
        In a separate thread, run HTTP Request, get back and process, return inputstream
    }

Cette méthode est appelée par plusieurs autres pour effectuer HttpRequests. Une fois le flux d'entrée renvoyé, les autres méthodes analysent des informations spécifiques.

24
mbauer14

La façon la plus simple de le faire serait simplement de faire quelque chose comme

//Body of your click handler
Thread thread = new Thread(new Runnable(){
  @Override
  public void run(){
    //code to do the HTTP request
  }
});
thread.start();

Cela provoquera l'exécution du code à l'intérieur de la méthode run() dans un nouveau thread d'exécution. Vous pouvez examiner une tâche asynchrone si vous le souhaitez, même si je ne l'ai jamais utilisée personnellement. Il s'agit d'un moyen rapide et simple de faire avancer les choses.

En ce qui concerne la transmission d'informations, j'utiliserais un objet gestionnaire qui vous permet effectivement de configurer une file d'attente de messages pour un thread donné et de lui transmettre des messages qui provoquent l'exécution de code spécifique. La raison pour laquelle vous devez le faire est que Android ne laissera aucun thread autre que le thread d'interface utilisateur mettre à jour l'interface utilisateur réelle.

Cela répond-il à votre question? Je sais que mon premier laissez-passer n'a pas entièrement résolu tous vos problèmes.

Edit Fondamentalement, ce que vous faites est de définir un objet gestionnaire dans votre Activity comme

private Handler handler_ = new Handler(){
    @Override
    public void handleMessage(Message msg){

    }

};

Vous créez également des constantes int statiques qui aident à dire au gestionnaire quoi faire. Vous les utilisez essentiellement pour permettre à plusieurs types de messages différents d'être transmis à une instance d'un gestionnaire. S'il n'y a qu'un seul message qui est renvoyé, vous n'avez pas à vous en soucier.

Par exemple

private static final int UPDATE_UI = 1;

Pour envoyer un message au gestionnaire que vous appelez

handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance));

Du gestionnaire:

private Handler handler_ = new Handler(){
    @Override
public void handleMessage(Message msg){
    switch(msg.what){
            case UPDATE_UI:
            InputStream is = (InputStream)msg.obj;
            //do what you need to with the InputStream
            break;
        }
    }

};

Alternativement, lorsque le inputStreamInstance est ajouté à l'objet Message, vous pouvez passer n'importe quel objet que vous aimez, donc si vous vouliez l'analyser dans une sorte d'objet conteneur ou quelque chose comme ça, vous pouvez également le faire. Il suffit de le restituer à cet objet depuis le gestionnaire.

74
Chris Thompson

Essayez d'utiliser AsyncTask. Goto this Link for more:

private class SyncIncoData extends AsyncTask<String, String, String> {
    ProgressBar pb;
    ProgressBar pbar;

    @Override
    protected String doInBackground(String... urls) {
        for (int i = 0; i <= 100; i++) {
            publishProgress(i);
        }
        return null;
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.VISIBLE);

    }

    @Override
    protected void onPostExecute(String result) {

        pb = (ProgressBar) findViewById(R.id.progressBarsync4);
        pb.setVisibility(View.INVISIBLE);

    }

    @Override
    protected void onProgressUpdate(String... values) {
        pbar = (ProgressBar) findViewById(R.id.progressBarpbar);
        pbar.setProgress(Integer.parseInt(values[0]));
        super.onProgressUpdate(values);
    }
}

Écrivez le programme de la requête http dans doinbackgroud()

5
Jin