1

我正在尝试从循环中调用 AsyncTask。它工作正常,但问题是执行所有请求需要更多时间。请建议我如何让它更快。

for (int i = 0; i < 6; i++) {
    response  = requestWeatherUpdate(location);
}

请求天气更新

private WeatherResponse requestWeatherUpdate(String location) {
        url = ""+ location;
        Log.d("URL for Weather Upadate", url);
        WeatherUpdateAsyncTask weatherReq = new WeatherUpdateAsyncTask();
        String weatherRequestResponse = "";
        try {
            weatherRequestResponse = weatherReq.execute(url).get();
            if (weatherRequestResponse != "") {
                parsedWeatherResponse = ParseWeatherResponseXML
                        .parseMyTripXML(weatherRequestResponse);
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return parsedWeatherResponse;

    }

使用回调

  public class WeatherUpdateAsyncTask extends AsyncTask<String, Void, String> {
    Context context;
    CallBack callBack;

    public WeatherUpdateAsyncTask(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected String doInBackground(String... arg0) {
        String responseString = "";
        HttpClient client = null;
        try {
            client = new DefaultHttpClient();
            HttpGet get = new HttpGet(arg0[0]);
            client.getParams().setParameter("http.socket.timeout", 6000);
            client.getParams().setParameter("http.connection.timeout", 6000);
            HttpResponse responseGet = client.execute(get);
            HttpEntity resEntityGet = responseGet.getEntity();
            if (resEntityGet != null) {
                responseString = EntityUtils.toString(resEntityGet);
                Log.i("GET RESPONSE", responseString.trim());
            }
        } catch (Exception e) {
            Log.d("ANDRO_ASYNC_ERROR", "Error is " + e.toString());
        }
        Log.d("ANDRO_ASYNC_RESPONSE", responseString.trim());
        client.getConnectionManager().shutdown();
        return responseString.trim();

    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        callBack.run(result);
    }

}

请求天气更新

 private WeatherResponse requestWeatherUpdate(String location) {
    url = ""
            + location;
    Log.d("URL for Weather Upadate", url);
    WeatherUpdateAsyncTask weatherReq = new WeatherUpdateAsyncTask(new CallBack() {
        @Override
        public void run(Object result) {
            try {
                String AppResponse = (String) result;
                response = ParseWeatherResponseXML
                        .parseMyTripXML(AppResponse);

            } catch (Exception e) {
                Log.e("TAG Exception Occured",
                        "Exception is " + e.getMessage());
            }
        }
    });
    weatherReq.execute(url);
    return response;

}

我在这里打电话

for (int i = 0; i < 4; i++) {
            inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            RelativeLayout layout = (RelativeLayout) inflater.inflate(
                    R.layout.sector_details, depart_arrivals_details, false);
            depart_time = (TextView)layout.findViewById(R.id.depart_time);
            depart_airport_city = (TextView)layout.findViewById(R.id.depart_airport_city);
            temprature = (TextView)layout.findViewById(R.id.temprature);
            humidity = (TextView)layout.findViewById(R.id.humidity);
            flight_depart_image = (ImageView)layout.findViewById(R.id.flight_depart_image);


            depart_time.setText("20:45");
            depart_airport_city.setText("Mumbai");
            /*
             * This part will be updated when we will se the request and get the response 
             * then we have to set the temp and humidity for each city that we have recived
             * */
            temprature.setText("");//Here i have set the values from the response i recived from the AsynkTask
            humidity.setText("");//Here i have set the values from the response i recived from the AsynkTask

            flight_depart_image.setImageResource(R.drawable.f1);

            depart_arrivals_details.addView(layout, i);
        }
4

4 回答 4

3
  1. 调用get()anAsyncTask会阻塞调用线程。不要那样做。而是将结果传递给onPostExecute().

  2. 从 Honeycomb 开始,默认实现在串行执行器上按顺序执行异步任务。要并行运行 asynctasks,请使用executeOnExecutor(THREAD_POOL_EXECUTOR, ...)而不是execute(...).

于 2013-10-04T11:29:57.360 回答
2

你不应该使用get(). 调用get()不会使调用异步。而是使用execute

weatherRequestResponse = weatherReq.execute(url).get();

get()

public final Result get ()

Added in API level 3
Waits if necessary for the computation to complete, and then retrieves its result.

Returns
The computed result.
Throws
CancellationException   If the computation was cancelled.
ExecutionException  If the computation threw an exception.
InterruptedException    If the current thread was interrupted while waiting.

用于并行执行executeOnExecutor

  weatherReq.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);

如果您的 asynctask 是您的活动类的内部类,您可以在onPostExecute. 如果不是,您可以使用接口作为回调。

从 Android 中的 AsyncTask 检索返回的字符串

如何从 AsyncTask 返回布尔值?

从讨论中你得到 NUllPointerException @temprature.setText(parsedWeatherResponse.getTempInC()+(char) 0x00B0);

你还没有初始化parsedWeatherResponse。你只声明了它

  parsedWeatherResponse = new WeatherResponse();
于 2013-10-04T11:31:27.867 回答
1

使用 executeOnExecutor(THREAD_POOL_EXECUTOR, ...) 并行运行异步任务。你也可以使用HttpURLConnection而不是 DefaultHttpClient/HttpGet

于 2013-10-04T11:50:19.427 回答
1

如果你想从 UI 线程与网络连接,这是相当困难的。“当应用程序尝试在其主线程上执行网络操作时引发的异常。

这仅针对面向 Honeycomb SDK 或更高版本的应用程序抛出。允许以早期 SDK 版本为目标的应用程序在其主事件循环线程上进行网络连接,但非常不鼓励这样做。请参阅文档设计响应性。”

如果您想克服此困难,请按照以下说明进行操作:

解决方案如下。我从另一个答案中找到了它。它对我有用。并将下面的 import 语句放入您的 java 文件中。

import android.os.StrictMode;

将以下代码写入 onCreate

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
于 2014-04-27T10:44:46.570 回答