2011-07-16 2 views
0

Une de mes activités envoie une requête http à un service Web pour obtenir des données météorologiques lorsque je démarre l'application.Android: l'activité est trop longue à afficher à cause du service Web Demande Http

Le problème que l'activité mettra 3-4 secondes à afficher en raison de la demande de service Web. (Testé sur l'appareil actuel)

Je sais que je ne fais pas cela de la bonne façon. Tout ce que je fais est sur la méthode onCreate, je fais la demande, récupérer le xml, analyser et afficher les données.

Quelle est la meilleure façon de traiter les demandes de service Web dans Android afin que l'application n'affiche pas un écran blanc pendant que la demande est faite? Peut-être quelques threads .......

Je sais que cela ne se produit pas sur d'autres applications que j'ai dans mon appareil qui font une demande pour obtenir des données en direct.

Notes:

1) Le xml je revenir est pas grand (5 éléments avec 5 éléments imbriqués sur chacun).

2) J'ai essayé avec le réseau 3G et Wifi mais le temps de réponse est toujours le même.

exemple de code:

@Override 
    public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.clock_weather); 

    // this is where it is making the request and parsing the xml. 
    WeatherSet set = getWeatherCondition("New York, NY"); 

    TextView currentWeather = (TextView) findViewById(R.id.current_weather); 
    currentWeather.setText("" + set.getWeatherCurrentCondition().getTempFahrenheit()); 

    TextView currentWeatherH = (TextView) findViewById(R.id.current_weatherH); 
    currentWeatherH.setText("H: " + set.getWeatherForecastConditions().get(0).getTempMaxFahrenheit()); 

    TextView currentWeatherL = (TextView) findViewById(R.id.current_weatherL); 
    currentWeatherL.setText("L: " + set.getWeatherForecastConditions().get(0).getTempMinFahrenheit()); 

    ImageView currentWeatherIcon = (ImageView) findViewById(R.id.current_weather_icon); 
    String imageUrl = set.getWeatherCurrentCondition().getIconURL(); 
    Drawable bitmapDrawable = getImageBitmap(imageUrl); 
    currentWeatherIcon.setImageDrawable(bitmapDrawable); 

    setForecastInfo(set, R.id.day1, R.id.day1_icon, R.id.day1_temp, 1 ); 
    setForecastInfo(set, R.id.day2, R.id.day2_icon, R.id.day2_temp, 2 ); 
    setForecastInfo(set, R.id.day3, R.id.day3_icon, R.id.day3_temp, 3);  
    setForecastInfo(set, R.id.day4, R.id.day4_icon, R.id.day4_temp, 4 ); 
} 

Répondre

5

le temps pour votre re La réponse est imprévisible - votre connexion réseau peut être très mauvaise et prendre quelques secondes pour transférer quelques octets.Donc, la façon correcte de le faire (comme vous le proposez) est d'utiliser le thread. Dans notre cas, Android fournit une classe très utile pour gérer ces situations - AsynTask. Après avoir lu les documents, vous remarquerez qu'il a 3 méthodes très puissantes qui peuvent vous aider

  1. onPreExecutefonctionne dans le thread d'interface - très utile pour montrer une fileuse ou un indicateur de progression pour montrer à l'utilisateur que vous font un travail en arrière-plan
  2. doInBackgroundfonctionne en arrière-plan - faire votre travail de fond ici
  3. onPostExecutedans le fil fonctionne ui - une fois terminé votre travail de fond cacher les progrès d'une d mettre à jour le gui avec les données nouvellement reçues.
+0

Merci à tous pour les réponses rapides et grands. – Sammy

+0

J'ai une question. Lorsque j'ouvre l'application de construction HTC dans la météo ou toute autre application météo du marché, elle ne montre aucune barre de progression et ne prend pas le temps de montrer la réponse. Serait-il en train de montrer des données anciennes et de les actualiser en arrière-plan après le lancement de l'activité? Serait-il acceptable de faire quelque chose comme ça pour une activité météorologique? – Sammy

+0

Ce n'est tout simplement pas le show progressialog. Vous pouvez le faire, mais sachez qu'il affichera des valeurs par défaut ou quelque chose de différent jusqu'à ce que l'AsyncTask définisse ce que vous changez (dans le onPostExecute) – Rob

0

Vous pouvez utiliser la classe AsynchTask pour votre web service.You pouvez écrire votre temps tâche sur doInBackground.Also vous pouvez utiliser un dialogue de progression. Here Vous pouvez voir comment utiliser AsynchTask.Vous pouvez également mettre à jour votre interface utilisateur pendant que le service Web analyse sans attendre l'analyse complète à l'aide de la méthode onPostUpdate.

0

Le temps de réponse est normal. Ne t'inquiète pas. Prenez le point d'exécuter l'appel de service Web dans un thread distinct. En ce qui concerne l'écran blanc, dès que vous démarrez l'appel de service Web, déclenchez une boîte ProgressDialog. Cela fonctionnera jusqu'à ce que vous receviez la réponse. Dès que vous recevez la réponse, fermez la boîte de dialogue progressDialog et démarrez la nouvelle activité dans laquelle vous pouvez afficher le résultat.

Utilisez les URL suivantes pour référence

http://www.helloandroid.com/tutorials/using-threads-and-progressdialog

http://thedevelopersinfo.wordpress.com/2009/10/16/showing-progressdialog-in-android-activity/

Je l'ai mis en œuvre l'idée que je te donne, et il fonctionne parfaitement.

Hope I était d'une aide

0

What is the best way to deal with webservice requests in Android so the application won't display a white screen while the request is being made?

Parce que vous avez dit « écran blanc » Je suppose que vous n'utilisez pas une boîte de dialogue de progression. Vous devez montrer un progrès fileuse/dialogue pour permettre à l'utilisateur savez que vous traitez.

avez-vous vérifier la taille des données est? Si les données est trop grande, vous ne pouvez vraiment pas quoi que ce soit, si vous avez le contrôle sur le service de son mieux pour réduire la taille.

2
private class getWeather extends AsyncTask<Context, Void, Cursor> { 

     ProgressDialog dialog = null; 

     protected void onPreExecute() { 
      dialog = ProgressDialog.show(CLASS.this, "", 
         "Loading. Please wait...", true); 
     } 

     @Override 
     protected Cursor doInBackground(Context... params) { 
      WeatherSet set = getWeatherCondition("New York, NY"); 
      return null; 
     } 

     protected void onPostExecute(Cursor c) { 
      dialog.dismiss(); 
     } 
    } 

Alors où vous avez WeatherSet set = getWeatherCondition("New York, NY"); maintenant, vous mettrez new getWeather().execute(this);

Je vous suggère de lire comment fonctionne AsyncTask, et pourquoi cela devrait fonctionner. Il sort de la méthode onCreate().

1

Ceci est AsyncTask CE QUI CONCERNE, je veux juste aider à comprendre le concept, il est vraiment utile:

 DownloadFilesTask dft = new DownloadFilesTask(this); 
     //Executes the task with the specified parameters 
     dft.execute(Void1...); 

     ... 
     ... 
     ... 

     dft.cancel(boolean); 

private class DownloadFilesTask extends AsyncTask<Void1, Void2, Void3> { 
     //Runs on the UI thread before doInBackground(Void1...) 
     protected void onPreExecute() { 

     } 
     //runs in BACKGROUNG threat 
     protected Void3 doInBackground(Void1... urls) { 
      //it can be invoked from doInBackground(Void1...) to publish updates 
      //on the UI thread while doInBackground(Void1...) is still running 
      publishProgress(Void2...); 
     } 
     //Runs on the UI thread after publishProgress(Void2...) is invoked 
     protected void onProgressUpdate(Void2... progress) { 

     } 
     //Runs on the UI thread after doInBackground(Void1...) has finished 
     protected void onPostExecute(Void3) { 

     } 
     //runs in UI threat after cancel(boolean) is invoked and 
     //doInBackground(Void1...) has finished 
     protected void onCancelled(Void3) { 

     } 
} 
Questions connexes