2011-06-13 10 views
8

Estoy usando AsyncTask en muchos lugares sin problemas.Patrón para hacer AsyncTask "procedural"

Ahora, con Honeycomb, todas las conexiones de red deben estar separadas por hilos de la interfaz de usuario, lo que en muchos casos necesita AsyncTasks en lugares donde antes era adecuada una conexión de red síncrona (Honeycomb lanzará una excepción para cualquier red de E/S en el hilo principal/ui).

Ahora, básicamente, me gustaría obtener algo así como Object result = MyAsyncTask().execute() ¿hay buenos patrones para esto?

He encontrado AsyncTask Android - Design Pattern and Return Values que tiene sentido y es también la forma en que GWT hace las cosas, pero de alguna manera esto suena como menear al perro por la cola (y entonces puede que yo sea el cerebro el que necesita algo más de torsión).

Respuesta

13

Yup. Estás cerca. Pruebe

Object result = MyAsyncTask().execute().get(); 
+0

Gracias - eso era exactamente lo que estaba buscando - cómo podría haberme perdido eso primero. Para algunas partes, el patrón GWT es bastante agradable, pero esto ... get() tiene mucho sentido cuando es necesario hasta que las operaciones asincrónicas hayan terminado. –

+7

Simplemente como un elemento de reflexión y para otros que tropiezan con esta respuesta, llamar a execute(). Get() desde el hilo de la interfaz de usuario es prácticamente lo mismo que ejecutar la operación en el hilo de la interfaz de usuario. Aunque esto evita generar la Excepción para las llamadas de red en el hilo principal, no evita las implicaciones de la acción. Su subproceso de interfaz de usuario se bloqueará hasta que se complete la acción de red. Posiblemente podría causar un punto muerto al tener un método postExecute porque ese método esperará a que el hilo principal esté disponible. En mi humilde opinión, usted está presentando un anti-patrón para AsyncTasks. –

4

Estoy seguro de que no desea realizar una transacción de red síncrona en el hilo de la interfaz de usuario, ¿verdad?

El patrón que uso es mantener el estado en la Actividad (que implementa un receptor) y luego llamar a AsycTask que realiza una devolución de llamada a su actividad en onPostExecute() (es decir, iniciar una intención que su actividad está escuchando). Su actividad puede entonces actualizar el estado de acuerdo con los extras en el intento, y continuar procesando. Básicamente se trata de una máquina de estados que se encuentra en su Actividad y que realiza su inicio de sesión y otras funciones. Todas las cosas de E/S de red se realizan en instancias de AsycTask que hacen que el estado se actualice a medida que se completan.

+0

Sí, no en el hilo de la interfaz de usuario. Antes de HC esto era posible (y hay lugares, donde tiene sentido), pero HC lanzará una excepción para cualquier llamada de red en el hilo de la interfaz de usuario. –

1

Si solo quiere bloquear su hilo, mientras que otro hilo hace el trabajo, podría considerar escribir su propia abstracción de tareas. Estoy pensando en algo como

public class MyTask <T> { 
    // define executor here 
    public T execute(Callable<T> c) { 
     Future<T> t = executor.submit(c); 
     return t.get(); 
    } 
}