2011-08-26 15 views
9

1) No entiendo por qué las muestras de Android casi usan AsyncTasks como clases internas privadas. Sé que es conveniente hacerlo de clase interna pero hace que nuestro archivo de clase sea más largo y difícil de leer. La aplicación de muestra ShelvesActivity of Shelves tiene incluso 845 líneas. ¿No crees que es un mal diseño o una mala construcción?Si AsyncTask no es una clase interna ... - algunas preguntas

2) Si realizo mi clase externa ScanStorageTask, ¿qué tengo que pasarle? toda la actividad o solo widgets usados?

Ejemplo: si debo usar un WebView, un botón y una barra ProgressBar en ScanStorageTask. utilizo este:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it. 

o esto:

ScanStorageTask task = new ScanStorageTask(webView, button, progressBar); 

Respuesta

14

No hay nada de malo en hacerlo externamente, y en realidad podría ser un mejor diseño. Aprobar los elementos de la interfaz de usuario es el tipo de acoplamiento ajustado que puede provocarle problemas cuando tiene una base de código realmente grande.

¿Por qué no hacerlo externamente y usar el patrón de "escucha" que emplean los controles de la interfaz de usuario?Convierta su ScanStorageTask en su propia clase, cree una interfaz OnCompleteListener con un método onComplete y transfiérala a su instancia de ScanStorageTask (exponga un método setOnCompleteListener o algo por el estilo). Entonces, onPostExecute simplemente puede hacer esto:

if(onCompleteListener != null) 
    onCompleteListener.onComplete(data); 

De esa manera, definir sus actualizaciones de la interfaz de usuario dentro de su actividad sobre la base de los datos. Es mejor separar las preocupaciones y mantendrá sus líneas de código por clase, ya que eso parece ser lo que preferiría. Si aún no lo tiene, cree una clase que represente los datos que necesita para ingresar y salir, y eso es lo que debe pasar a la tarea como un parámetro del método de ejecución y lo que onPostExecute pasa a onComplete.

+0

Tiene razón, pasar elementos de IU es muy problemático. Realmente quiero hacer algo para separar AsyncTasks de Activity. Gracias por la idea de patrón de oyente. – Emerald214

+0

Desearía que tuvieras un código de muestra – CodyBugstein

+1

@Imray. Avísame si esto ayuda. Creé esta clase, y ahora extiendo si para todas mis tareas asincrónicas: https://github.com/aguynamedrich/beacon-utils/blob/master/Library/src/us/beacondigital/utils/tasks/Task.java – Rich

6

Las clases internas le permiten manipular la interfaz de usuario de una combinación externa Activity dentro onPreExecute(), onPostExecute() y onProgressUpdate() sin pasar toda la estructura (s) interfaz de usuario para el AsyncTask. Solo puede usar las funciones de actividades para eso.

Esto es útil ya que manipular la IU no es el objetivo principal de una AsyncTask. Está haciendo un trabajo de fondo que no es de UI. Y para eso, lo que generalmente tiene que aprobar son algunos argumentos para hacer este trabajo (por ejemplo, proporcionar una URL para descargar un archivo).

Cuando declara su AsyncTask externo, básicamente no puede acceder a sus recursos de IU dentro de onPreExecute() (no se le pasan argumentos a esto en absoluto), y muy difícil dentro de las otras dos funciones de UI.

Yo diría que AsyncTask está hecho para ser utilizado como una clase interna para hacer el trabajo y actualizar el hilo de la interfaz de usuario. Ver la descripción:

AsyncTask permite el uso adecuado y fácil del subproceso de interfaz de usuario. Esta clase permite realizar operaciones en segundo plano y publicar resultados en el subproceso UI sin tener que manipular subprocesos y/o controladores.

(desde the class documentation)

+0

Se metió en este problema simular anoche con un httpRequest enhebrado. Cuando la solicitud devuelve un mensaje al controlador, deseo actualizar el contenido de mi actividad, pero no puedo, ya que está en una clase externa. Diría que en Android y otros sistemas móviles a veces hace más desde que se hace todo dentro de la actividad. Se pierde legibilidad, pero lo más probable es que se guarden algunos ciclos – NSjonas

+0

Los datos de vista/actividad generalmente se pasan a AsyncTask en su constructor. –

2
  1. Personalmente me creer que si se utiliza la clase sólo en un punto, entonces es más legible para definir también allí - clase interna de ahí el anon.

  2. No importa. Desde la perspectiva del diseño, solo transmitiría los datos que realmente se necesitan. Sin embargo, debe tener en cuenta un posible inconveniente: cuando la instancia de actividad se desactiva (oculta u orientación cambiada) y el hilo de fondo sigue ejecutándose e intenta mostrar algunos cambios, puede obtener varios errores o no mostrar nada.

4

Tuve el mismo problema en la aplicación de mayo. Quería establecer una comunicación con una PC usando un Socket y quería que mi código fuera reutilizable desde varias Actividades/Fragmentos.

En primer lugar he intentado no utilizar una clase interna, pero es muy conveniente cuando se tiene que actualizar la interfaz de usuario, así que encontró una solución alternativa:
creé un wich AsyncTask clase externa encargada de comunicarse con el pc y yo creamos clases internas en cada una de mis actividades/fragmentos con solo una anulación del método onPostExecute(). De esta forma puedo reutilizar mi código Y actualizar la UI.

Si solo desea obtener el resultado de la tarea y si la capacidad de respuesta no es esencial para su aplicación, puede utilizar el método get() de la clase AsyncTask.

+0

Usar 'get()' es exactamente lo que se debe usar en caso de que solo necesite el resultado de su proceso en segundo plano. ¡Funciona de maravilla! – kaolick

Cuestiones relacionadas