多次并行调用AsyncTask

时间:2013-10-04 11:24:31

标签: android android-asynctask

我试图从循环中调用AsyncTask。它工作正常但问题是它需要花费更多的时间来执行所有请求。请告诉我如何才能让它更快。

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

requestWeatherUpdate

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;

    }

二手CallBack

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

}

requestWeatherUpdate

 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;

}

Frm在这里我打电话

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 个答案:

答案 0 :(得分:3)

  1. get()上调用AsyncTask会阻止调用线程。不要那样做。而是将结果传递给onPostExecute()中的调用者。

  2. 从Honeycomb开始,默认实现在串行执行器上顺序执行asynctasks。要并行运行asynctasks,请使用executeOnExecutor(THREAD_POOL_EXECUTOR, ...)代替execute(...)

答案 1 :(得分: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中更新ui。如果不是,你可以使用接口作为回调。

Retrieving a returned string from AsyncTask in Android

How do I return a boolean from AsyncTask?

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

您尚未初始化parsedWeatherResponse。你只宣布了它

  parsedWeatherResponse = new WeatherResponse();

答案 2 :(得分:1)

使用executeOnExecutor(THREAD_POOL_EXECUTOR,...)并行运行asynctasks。您也可以使用HttpURLConnection代替DefaultHttpClient / HttpGet

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