2010-03-22 12 views
15

Estoy obteniendo muchas miniaturas desde un servidor remoto y mostrándolas en una vista de cuadrícula, usando AsyncTask. El problema es que mi vista de cuadrícula muestra 20 miniaturas a la vez, por lo que crea 20 AsyncTasks y comienza 20 ejecuciones, una por miniatura.AsyncTask, RejectedExecutionException y Task Limit

Obtengo RejectedExecution excepción en mi código. Recuerdo haber leído en alguna parte que hay un límite en el número de tareas que AsyncTask puede tener en su cola a la vez, podría estar golpeando eso. ¿Fue levantado este bar?

¿Hay alguna manera de aumentar este límite? ¿Es seguro simplemente ignorar esta excepción? (Teniendo un bloque vacío catch(RejectedException e){}?)

Estoy ejecutando este código en el emulador de Android 1.6 y el nivel API en mi código (minSDKVersion es 3). [EDIT: Agregado SDK y API de nivel info]

Respuesta

17

Recuerdo haber leído en alguna parte que no un límite en el número de tareas que AsyncTask puede tener en su cola a la vez , yo podría estar golpeando eso. ¿Fue levantada esta barra?

AsyncTask parece apoyar actualmente 10 hilos y una cola de la profundidad de trabajo 10. En teoría, eso sólo apoyaría 20 artículos ... si nada más está usando AsyncTask.

¿Hay alguna manera de aumentar este límite?

Tome el código fuente, modifíquelo, póngalo en su propio paquete y utilícelo. Lo hice con mi AsyncTaskEx, aunque está basado en la fuente Android 1.5.

¿Es seguro ignorar esta excepción ?

Su trabajo no se pondrá en cola para su ejecución. Si eso es "seguro" depende de usted. No tengo conocimiento de ningún otro impacto en la infraestructura AsyncTask.

+0

Gracias Marque por su respuesta y también por compartir su código! Por cierto, según el comentario de Romain Guy aquí: http://stackoverflow.com/questions/990948/simple-thread-management-java-android el límite parece haberse relajado. – Samuh

+0

Desafortunadamente, no puedo confirmar su declaración. Lo que tengo arriba es de mi examen del código fuente (como se encuentra a través de Google Code Search). Sin embargo, podría ser que estoy malinterpretando el código. – CommonsWare

+0

Estoy llegando al mismo problema. Sería perfectamente feliz de tener mis tareas ejecutadas en secuencia en lugar de en paralelo. ¿Hay alguna forma de hacer esto? ¿O vuelvo a implementar una cola de trabajo? –

1

"Seguro" para ignorar: debe asegurarse de que cualquier tipo de notificación que estaba planeando hacer en la ejecución posterior se realice aquí cuando detecta el error; de lo contrario, podría dejar algo colgado si el otro el código hace suposiciones sobre la respuesta auditiva de esta tarea.

7

He hecho exactamente esto mismo en una aplicación.

Lanzar 20 subprocesos paralelos a la vez para descargar miniaturas desde un servidor y enviarlas a un adaptador de datos no me parece una buena idea. Todos esos hilos se tropezarán unos con otros y se meterán en el camino del otro.

En lugar de eso, lanzaría solo un hilo, haría que recogiera las miniaturas en un bucle y las agregaría al adaptador a medida que llegaran.

2

Puede usar el ejecutor en serie con AsyncTask.executeOnExecutor, para serializar sus tareas, pero eso limitará la tarea a una sola tarea simultánea en ese momento. Sin embargo, podría ser bueno al obtener miniaturas:

myAsyncTask.executeOnExecutor (MyAsyncTask.SERIAL_EXECUTOR, [params]);

2

El problema es que el número de pendientes AsyncTasks para AsyncTask.THREAD_POOL_EXECUTOR es 128. Una vez que la cola se llena no hay nuevos AsyncTasks pueden poner en cola.

desde el código fuente AsyncTask:

private static final BlockingQueue<Runnable> sPoolWorkQueue = 
     new LinkedBlockingQueue<Runnable>(128); 

En mi opinión ese límite no tiene ningún sentido en absoluto y AsyncTask.SERIAL_EXECUTOR tiene una cola ilimitada.