2012-03-31 4 views
2

J'utilise une application où j'ai juste besoin de télécharger une paire de coordonnées pour Google Maps à partir d'un serveur mysql. Je peux le faire avec succès en utilisant PHP et un httpost normal, mais mon application se bloque pendant quelques secondes quand je le fais.Async HTTP post android

J'ai lu que vous devez rendre httppost asycronous afin d'éviter ce gel jusqu'à ce que le serveur finisse le prossess et envoie les résultats.

Le point est que j'ai besoin de ce résultat dans un tableau json comme le httpost normal.

Par exemple si j'avais ce httppost.

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php"); 

try { 
    // Add your data 
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
    nameValuePairs.add(new BasicNameValuePair("id", "12345")); 
    nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!")); 
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

    // Execute HTTP Post Request 
    HttpResponse response = httpclient.execute(httppost); 
} catch (ClientProtocolException e) { 
    // TODO Auto-generated catch block 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
} 

String result11 = null; 
// convert response to string 
try { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(is11, "iso-8859-1"), 8); 
    StringBuilder sb = new StringBuilder(); 
    sb.append(reader.readLine() + "\n"); 
    String line = "0"; 
    while ((line = reader.readLine()) != null) { 
     sb.append(line + "\n"); 
    } 
    is11.close(); 
    result11 = sb.toString(); 
} catch (Exception e) { 
    Log.e("log_tag", "Error converting result " + e.toString()); 
} 

// parsing data 
try { 
    JSONArray jArray1 = new JSONArray(result11); 
} catch (JSONException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Comment puis-je convertir en un poste asynchrone afin que je puisse éviter le gel?

+0

Je ne sais pas comment votre code pourrait même compiler tel qu'il est, mais s'il vous plaît, utilisez [ 'EntityUtils.toString (response.getEntity())'] (http://stackoverflow.com/a/2324739/180740) au lieu d'avoir votre propre partie BufferedReader-n-StringBuilder. Le premier est moins de code, gère correctement les erreurs et obéit au codage de caractères envoyé par le serveur. –

Répondre

1

En supposant que vous voulez faire sur un bouton clic:

public void onClick(View v) { 
    new Thread(new Runnable() { 
     public void run() { 
      //your code here 
     } 
    }).start(); 
} 

Fondamentalement, vous mettez IO opération intensive dans un thread séparé (pas votre thread d'interface utilisateur) de telle sorte que l'interface utilisateur ne gèle pas.

+0

essayer dans un moment et mal vous répondre. Merci beaucoup pour votre réponse :) – user878813

2

Plutôt que de simplement démarrer un nouveau thread, c'est une meilleure idée d'opter pour un AsyncTask à part entière. Cela permet un meilleur contrôle des choses.

private class DoPostRequestAsync extends AsyncTask<URL, Void, String> { 
    protected String doInBackground(URL url) { 
     //Your download code here; work with the url parameter and then return the result 
     //which if I remember correctly from your code, is a string. 
     //This gets called and runs ON ANOTHER thread 
    } 

    protected void onPostExecute(String result) { 
     //This gets called on the interface (main) thread! 
     showDialog("Done! " + result); 
    } 
} 

Placez la nouvelle implémentation de classe dans la classe de votre activité souhaitée. Pour plus d'informations sur AsyncTask s'il vous plaît suivez ce lien:

http://developer.android.com/reference/android/os/AsyncTask.html

5

Il y a une belle classe AsyncTask qui peut être utilisé pour exécuter facilement des tâches asynchrones. Si vous intégrez votre code dans une telle sous-classe, vous pourriez finir avec ceci:

public class FetchTask extends AsyncTask<Void, Void, JSONArray> { 
    @Override 
    protected JSONArray doInBackground(Void... params) { 
     try { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php"); 

      // Add your data 
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      nameValuePairs.add(new BasicNameValuePair("id", "12345")); 
      nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!")); 
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

      // Execute HTTP Post Request 
      HttpResponse response = httpclient.execute(httppost); 

      BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "iso-8859-1"), 8); 
      StringBuilder sb = new StringBuilder(); 
      sb.append(reader.readLine() + "\n"); 
      String line = "0"; 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
      reader.close(); 
      String result11 = sb.toString(); 

      // parsing data 
      return new JSONArray(result11); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    @Override 
    protected void onPostExecute(JSONArray result) { 
     if (result != null) { 
      // do something 
     } else { 
      // error occured 
     } 
    } 
} 

Vous pouvez commencer la tâche à l'aide:

new FetchTask().execute(); 

Ressources supplémentaires:

3

Je suggère d'utiliser la bibliothèque android-async-http (http://loopj.com/android-async-http/). Il rend les appels HTTP asynchrones simples et élégants.

+1

Malheureusement, il y a seulement quelques démos disponibles qui permettent à un débutant de comprendre comment mettre tout cela ensemble, comme dans ce cas de publier des données à une URL et de traiter une réponse en utilisant JSON. Je comprends que tout est là et semble être très puissant et intelligent, mais quelques exemples seraient certainement aider. – richey

+1

Je l'ai utilisé et je l'ai trouvé facile à démarrer. J'ai commencé avec l'exemple de code donné dans la section "Utilisation recommandée" de http://loopj.com/android-async-http/. J'apprends et je fais certaines choses en cours de route, comme persister les cookies, le faire fonctionner avec SSL (fiable et non fiable), ajouter une vérification pour voir si l'appareil est en ligne ou pas, etc. Je pense que tous ces problèmes seront doivent être traitées si vous utilisez cette bibliothèque ou API Android. – krishnakumarp

1

Utilisez une bibliothèque HTTP asynchrone comme ion. https://github.com/koush/ion

Toutes les plaquettes filetées et asynchrones seront traitées pour vous.

Il s'agit de votre même code, asynchrone, utilisant Ion. Beaucoup plus simple:

Ion.with(context) 
.load("http://www.yoursite.com/script.php") 
.setBodyParameter("id", "12345") 
.setBodyParameter("stringdata", "AndDev is Cool!") 
.asJsonArray() 
.setCallback(new FutureCallback<JsonArray> { 
    void onCompleted(Exception e, JsonArray result) { 
    // do something with the result/exception 
    } 
});