1

I am trying to call AsyncTask from a loop.It is working properly but the issue is it taking quite more time to execute all the request.Please suggest me how could i make it more fast .

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;

    }

Used 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 here i calling

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);
        }
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • 1
    Can you elaborate more why you need looping for async ? – Usman Kurd Oct 04 '13 at 11:26
  • If you are using version 4.0 or above async tasks executing in calling order, not at the same time. Try to execute like this : "AsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");" – invisbo Oct 04 '13 at 11:27
  • see the issue is i am calling asynk task in a for loop that is taking more time so is there any way to reduce the time of execution –  Oct 04 '13 at 11:29
  • @invisbo you mean that by calling execute() they will run all in the same thread in sequence? – lelloman Oct 04 '13 at 11:30
  • @Rahul yes that is right – invisbo Oct 04 '13 at 11:54

4 Answers4

3
  1. Calling get() on an AsyncTask blocks the calling thread. Don't do that. Instead pass the results to the caller in onPostExecute().

  2. Starting with Honeycomb, the default implementation executes asynctasks sequentially on a serial executor. To run asynctasks parallely, use executeOnExecutor(THREAD_POOL_EXECUTOR, ...) instead of execute(...).

laalto
  • 150,114
  • 66
  • 286
  • 303
  • see i have done this because i have to set the values that i will get from the response to the layout that i am infalting in the loop –  Oct 04 '13 at 11:32
2

You should not use get() . Calling get() does not make the call asynchronous. Instead use 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.

For parallel execution use executeOnExecutor

  weatherReq.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);

If your asynctask is an inner class of your activity class you can update ui in onPostExecute. If its not you can use a interface as a callback.

Retrieving a returned string from AsyncTask in Android

How do I return a boolean from AsyncTask?

From the discussion you get NUllPointerException @ temprature.setText(parsedWeatherResponse.getTempInC()+(char) 0x00B0);

You have not initialized parsedWeatherResponse. You have only declared it

  parsedWeatherResponse = new WeatherResponse();
Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
1

use executeOnExecutor(THREAD_POOL_EXECUTOR, ...) to run asynctasks parallely. also you can use HttpURLConnection instead of DefaultHttpClient/HttpGet

Prachi
  • 2,559
  • 4
  • 25
  • 37
1

If you want to connect with network from UI thread , it is quitly difficult. "The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness."

If you want to overcome this difficulty then following bellow instruction:

The solution is given below. I found it from another answer. It is working for me. And below import statement into your java file.

import android.os.StrictMode;

Write below code into onCreate

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87