Android:由于Web服务Http请求,活动需要很长时间才能显示

时间:2011-07-16 17:33:49

标签: java android web-services

当我启动应用程序时,我的一个活动向Web服务发出http请求以获取一些天气数据。

由于Web服务请求,活动将需要3-4秒才能显示的问题。 (在实际设备上测试)

我知道我没有以正确的方式这样做。我所做的只是在onCreate方法上,我正在发出请求,重新获取xml,解析并显示数据。

在Android中处理Web服务请求的最佳方法是什么,以便在发出请求时应用程序不会显示白屏?也许有些线程.......

我知道我的设备中的其他应用程序没有发生请求获取实时数据。

注意:

1)我回来的xml不是那么大(5个元素,每个元素有5个嵌套元素)。

2)我尝试使用3G网络和Wifi,但响应时间仍然相同。

示例代码:

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

6 个答案:

答案 0 :(得分:5)

您的响应时间不可预测 - 您的网络连接可能非常糟糕,需要几秒钟才能传输几个字节。所以正确的方法(如你所建议的)是使用线程。在我们的例子中,android提供了非常有用的类来处理这种情况 - AsynTask。阅读文档后,您会注意到它有3种非常强大的方法可以帮助您

  1. onPreExecute 在ui主题中运行 - 非常有助于显示一些微调器或一些进度指示器,以向用户显示您在后台进行某些工作
  2. doInBackground 在后台运行 - 在此处开展背景工作
  3. onPostExecute 在ui主题中运行 - 当您完成后台工作后,隐藏进度并使用新接收的数据更新gui。

答案 1 :(得分: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();
        }
    }

然后,您现在拥有WeatherSet set = getWeatherCondition("New York, NY");,您将放置new getWeather().execute(this);

我建议阅读AsyncTask的工作原理,并了解为什么这应该有效。它超出了onCreate()方法。

答案 2 :(得分:1)

这是关于 AsyncTask ,我只想帮助理解这个概念,它确实很有用:

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

        }
}

答案 3 :(得分:0)

您可以将AsynchTask类用于Web服务。您可以在doInBackground上编写耗时的任务。此外,您还可以使用进度对话框。 Here您可以看到如何使用AsynchTask。您还可以在Web服务解析时更新UI,而无需等待使用onPostUpdate方法进行完整解析。

答案 4 :(得分:0)

响应时间正常。别担心。请在单独的线程中运行Web服务调用。

关于白屏,只要启动Web服务调用,就会触发ProgressDialog框。这将持续到您收到回复。收到响应后,请立即关闭progressDialog框并启动新活动,以显示结果。

使用以下网址作为参考

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

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

我已经实现了我给你的想法,它完美无缺。

希望我有所帮助

答案 5 :(得分: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?

因为您说'白色屏幕'我假设您没有使用进度对话框。您需要显示进度微调器/对话框,让用户知道您正在处理。

您是否检查过数据有多大?如果数据太大,你真的无法做任何事情,如果你能控制服务,最好减小尺寸。