2012-08-28 10 views
28

Estoy usando Android SDK 4.0.3 API15 y quiero ejecutar varias AsyncTasks de forma paralela. Estoy obteniendo mis datos del servidor web y animándolos (10 fps) en tiempo real. Pero dependiendo de las operaciones del usuario, necesito enviar algunos datos al servidor web también. Cuando esto ocurre, mi animación se detiene brevemente (el envío de datos entra en la cola y la obtención de datos lo espera para finalizar) y, por lo tanto, no puedo captar el tiempo real.Ejecutando múltiples AsyncTask's Parallely

Esto answer es bastante explicativo, pero no pude hacerlo funcionar. Entonces cualquier ayuda será muy apreciada.

Creo que necesito para usar esta función para lograr que:

AsyncTask.executeOnExecutor(Executor exec, Params... params) 

pero no puedo pasar un ejecutor como parámetro y no puedo crear una instancia de un ejecutor. Esta es mi clase AsyncTask:

public class GetPlayers extends AsyncTask<String, Void, String> { 
    @Override 
    protected String doInBackground(String... urls) { 

     Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 

     rawData=""; 
     for (String url : urls) { 
      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(url); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       InputStream content = execute.getEntity().getContent(); 

       BufferedReader buffer = new BufferedReader(new InputStreamReader(content)); 
       if((rawData = buffer.readLine()) == null){ 
        rawData = "error"; 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     return rawData; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     manipulate(); 
    } 
} 

Y ejecutarlo así:

GetPlayers task = new GetPlayers(); 
requestString = "web adress is here..."; 
task.execute(new String[] { requestString }); 
+0

¿Qué quiere decir con "no pasar un ejecutor como parámetro y no puedo crear instancias de un ejecutor"? ¿Has marcado developer.android.com/reference/java/util/concurrent/Executor.html, http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html? ¿Qué ejecutor exacto estás tratando de usar? – sandrstar

+0

En realidad, no tengo mucha experiencia en ejecutores. Así que traté de crear una instancia de la clase Executor. Por lo que he entendido desde el enlace, necesito usar ThreadPoolExecutor. Lo buscaré. Gracias. – Srht

+0

Derecha, Executor es solo una interfaz y no se puede crear una instancia. Puede ver la sección 'Subclases indirectas conocidas' de los documentos del ejecutor para los ejecutores presentados. Sin embargo, el típico parece ser ThreadPoolExecutor. – sandrstar

Respuesta

55

Así es como lo hago:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
    new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
} else { 
    new MyAsyncTask().execute(); 
} 

donde MyAsyncTask es subclase AsyncTask regular. O se puede envolver todo esto en clase de ayuda:

class TaskHelper { 

    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task) { 
     execute(task, (P[]) null); 
    } 

    @SuppressLint("NewApi") 
    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task, P... params) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
      task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); 
     } else { 
      task.execute(params); 
     } 
    } 
} 

y luego acaba de hacer:

TaskHelper.execute(new MyTask()); 

o

TaskHelper.execute(new MyTask(), args); 

o

TaskHelper.execute(new MyTask(constructorParams), args); 
+0

¿Cómo puedo pasar mi argumento a eso? ¿Me gusta esto? new MyAsyncTask(). executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR, new String [] {requestString}); – Srht

+0

SIEMPRE comience con la documentación de SDK. No es perfecto, pero es útil .. En 'executeOnExecutor()': http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params. ..% 29 para que pueda pasar sus parámetros –

+0

Lo he visto y leído antes de hacer la pregunta, pero no sabía cómo usar eso. Traté de agregar 'executeOnExecutor (Executor exec, Params ... params)' a mi definición de clase y, por lo que puedes adivinar, no funcionó. Soy un novato, pero trato de hacer las cosas solo. En este caso, simplemente no sé (y no pude encontrar) el uso adecuado de esto: 'new MyAsyncTask(). ExecuteOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR);' Así que muchas gracias por esta información que funcionó como un milagro. Y por favor, no te frustres :) – Srht

0

Este problema ocurrió a mí , al actualizar mi aplicación en AndroidStudio a sdk 25 de Intelliy usando Android 2.3 Solo el pequeño cambio (executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR, string1, ...);) funciona perfectamente. Tengo una AsyncTask ejecutándose en un servicio para descargar y creo AsyncTasks para subir sin servicio.

Cuestiones relacionadas