开发者

Android: Activity taking too long to display because of web service Http Request

One of my activities make a http request to a webservice to get some weather data when I start the application.

The issue that the activity will take 3-4 seconds to display because of the webservice request. ( Tested on actual device )

I know I m not doing this the right way. All I m doing is on the onCreate method, I m making the request , getting the xml back, parsing and displaying the data.

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? Maybe some threads.......

I know this is not happening on other application I have in my device that make request to get live data.

Notes:

1) The xml I getting back is not that big ( 5 elements with 5 nested elements on each one).

2) I tried with the 3G network and Wifi but the response time is still the same.

sample开发者_如何学编程 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  );
}


The time for your response is unpredictable - your network connection can be very poor and take seconds to transfer a few bytes. So the correct way to do this ( as you propose ) is to use thread. In our case android provides very useful class to handle this situations - AsynTask. After you read the docs you will notice that it has 3 very powerful methods that can help you

  1. onPreExecute runs in the ui thread - very helpful to show some spinner or some progress indicator to show the user that you are doing some work in background
  2. doInBackground runs in background - do your background work here
  3. onPostExecute runs in the ui thread- when your are done with your background work hide the progress and update the gui with the newly received data.


    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();
        }
    }

Then where you have WeatherSet set = getWeatherCondition("New York, NY"); now, you'll put new getWeather().execute(this);

I suggest reading how the AsyncTask works, and see why this should work. It goes outside the onCreate() method.


This is regarding AsyncTask, I just want to help understanding the concept, it is really useful:

        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) {

        }
}


You can use AsynchTask class for your web service.You can write your time consuming task in on doInBackground.Also you can use a progress Dialog. Here You can see how to work with AsynchTask.You can also update your UI while web service is parsing without waiting for the complete parsing using onPostUpdate method.


The response time is normal. Don't worry. Make it a point to run the web-service call in a separate thread.

Regarding the white screen, as soon as you start the web service call, fire a ProgressDialog box. This will run till you receive the response. As soon as you receive the response, dismiss the progressDialog box and start the new activity where you can display the result.

Use the following URLs for reference

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

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

I have implemented the idea I'm giving you and it works perfectly.

Hope I was of some help


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?

Because you said 'white screen" I am assuming you are not using a progress dialog. You need to show a progress spinner/dialog to let the user know you are processing.

Have you check how large the data is? If the data is too large you really cant do anything , if you have control over the service its best to reduce the size.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜