2013-10-04 4 views
1

Я пытаюсь вызвать 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); 
     } 
+1

Можете ли вы подробнее, почему вы должны зацикливание для асинхронном? –

+0

Если вы используете асинхронные задачи версии 4.0 или выше, выполняемые в порядке вызова, не в одно и то же время. Попробуйте выполнить так: «AsyncTask(). ExecuteOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR,« »); – invisbo

+0

см. Вопрос: я вызываю задачу asynk в цикле for, который занимает больше времени, так что есть ли способ сократить время выполнения –

ответ

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. Если его нет, вы можете использовать интерфейс в качестве обратного вызова.

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(); 
+0

. Мне нужно обновить значения макета также в цикле, который i am infalting –

+0

@Rahul вы можете использовать интерфейс в качестве обратного вызова – Raghunandan

+0

У меня есть его, но он не udpdating моих значений, так что, почему я использовал это, если я скажу, что могу поставить свой код состязания –

3
  1. Вызов get() на AsyncTask блокирует вызывающий поток. Не делай этого. Вместо этого передайте результаты вызывающему абоненту в onPostExecute().

  2. Начиная с Honeycomb, реализация по умолчанию выполняет асинхронные операции последовательно на последовательном исполнителе. Для параллельной работы asynctasks используйте executeOnExecutor(THREAD_POOL_EXECUTOR, ...) вместо execute(...).

+0

см. Я сделал это, потому что мне нужно установить значения, которые я получу от ответа на макет, который я делаю в цикле –

1

использование executeOnExecutor (THREAD_POOL_EXECUTOR, ...) для запуска asynctasks паралельно. также вы можете использовать HttpURLConnection вместо DefaultHttpClient/HttpGet

1

Если вы хотите соединиться с сетью из нити пользовательского интерфейса, это очень сложно. «Исключение, которое возникает, когда приложение пытается выполнить сетевую операцию в своем основном потоке.

Это предназначено только для приложений, предназначенных для SDK Honeycomb или выше. Приложениям, ориентированным на более ранние версии SDK, разрешено создавать сети по своим основным потокам цикла событий, но это сильно обескураживает. См документ Проектирования для отзывчивости «

Если вы хотите, чтобы преодолеть эту трудность, то следуя сильфон инструкции:.

Решения даются ниже я нашел другой ответ он работает на меня и ниже импорт... заявление в файл 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); 
} 
Смежные вопросы