繁体   English   中英

Android:由于 web 服务 Http 请求,活动显示时间过长

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

当我启动应用程序时,我的一项活动向 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  );
}

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

  1. onPreExecute在 ui 线程中运行- 非常有助于显示一些微调器或一些进度指示器以向用户显示您正在后台做一些工作
  2. doInBackground在后台运行- 在这里做你的后台工作
  3. onPostExecute在 ui 线程中运行- 当您完成后台工作时,隐藏进度并使用新收到的数据更新 gui。
    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()方法。

这是关于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) {

        }
}

您可以将 AsynchTask class 用于您的 web 服务。您可以在 doInBackground 上编写耗时的任务。也可以使用进度对话框。 在这里,您可以看到如何使用 AsynchTask。您还可以在 web 服务正在解析时更新您的 UI,而无需等待使用 onPostUpdate 方法完成解析。

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

关于白屏,一旦您启动 web 服务调用,就会触发 ProgressDialog 框。 这将一直运行,直到您收到响应。 收到响应后,立即关闭进度对话框并启动可以显示结果的新活动。

使用以下 URL 作为参考

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

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

我已经实现了我给你的想法,并且效果很好。

希望我能有所帮助

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?

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

你检查过数据有多大吗? 如果数据太大你真的无能为力,如果你可以控制服务最好减少大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM