Tema 4 3_4_interfaces_de_usuario

Post on 01-Dec-2014

1.153 views 0 download

description

Tema 4.3.4. Hebras e Internacionalización. Interfaz Yamba.

Transcript of Tema 4 3_4_interfaces_de_usuario

Análisis y Diseño de Software

Departamento de Ingeniería de Sistemas Telemáticoshttp://moodle.dit.upm.es

Interfaces de UsuarioHebras e Internacionalización.Interfaz Yamba

Carlos A. Iglesias <cif@gsi.dit.upm.es>

Interfaces de Usuario 2

Teoría

Ejercicio práctico en el ordenador

Ampliación de conocimientos

Lectura / Vídeo / Podcast

Práctica libre / Experimentación

Leyenda

Interfaces de Usuario 3

Temario● 4.1 Introducción a Android [Gar10, cap1-2 ]

● 4.2 Desarrollo con Android [Gar10, cap3-5]

● 4.3 Interfaces de Usuario [Gar10, cap6]

– 4.3.1 Ejemplo SobreTeleco– 4.3.2 Layouts y Views– 4.3.3 Widgets y Trazas. Interfaz del proyecto Yamba– 4.3.4. Hebras e internacionalización. Interfaz Yamba.

● 4.4 Intenciones y Servicios [Gar10, cap7-8]

● 4.5 Acceso a Datos [Gar10, cap9]

Interfaces de Usuario 4

Bibliografía

● Libro de texto: – [Gar10] Learning Android, Marko Gargenta,

O'Reilly, 2010. Disponible en http://ofps.oreilly.com/titles/9781449390501/

– Capítulos 6– http://www.youtube.com/watch?v=-P1eiRy-klk&list=PLE08A97D36D5A255F&index=10&feature=plpp_video

– http://www.youtube.com/watch?v=CzKYgi80yUw&list=PLE08A97D36D5A255F&index=11&feature=plpp_video

● Android Developers– http://developer.android.com/guide/topics/fundamentals.html

– http://developer.android.com/guide/topics/ui/index.html

Interfaces de Usuario 5

Objetivos

● Entender cómo funcionan la concurrencia y las hebras en Android

● Aprender a internacionalizar una aplicación

Interfaces de Usuario 6

Hebras en Android

● Android se basa en Linux, por lo que utiliza el sistema de gestión de hebras de linux

● Vamos a ver cómo usar las hebras al programar en Android

Interfaces de Usuario 7

Ejecución Monohebra

● Por defecto, una aplicación Android ejecuta sólo una hebra (single thread):– Cada instrucción se ejecuta, una a

continuación de otra– Cada llamada es bloqueante– La hebra que se ejecuta es la hebra de interfaz

de usuario (UI thread), es responsable de 'pintar' y de capturar los eventos del usuario

– Ejecución monohebra:

Interfaces de Usuario 8

¿Qué pasa si se cuelga una actividad?

● El sistema operativo está 'atento', y si una actividad no responde (normalmente 5 segundos), nos avisa para que 'la matemos'– Diálogo ANR (Application Not Responding)

Interfaces de Usuario 9

Problema monohebra: bloqueo UI

Solución: usamos hebras

Interfaces de Usuario 10

Ejemplo

● Una aplicación que se descarga un fichero

Android in Practice, Collins et al., 2011,Cap 6, Manning. Ejemplo disponible en http://www.manning.org/collins

Interfaces de Usuario 11

Interfaz main.xml (I)

Interfaces de Usuario 12

Interfaz main.xml (II)

Interfaces de Usuario 13

Actividad: SimpleImageDownload (I)

Creo un objeto 'Runnable' para descargar la imagen

Interfaces de Usuario 14

Actividad: SimpleImageDownload (II)

Al pinchar el botón, creo una hebra con el objeto Runnable y ejecuto start()

Interfaces de Usuario 15

Para ver si ha terminado... trazas

Interfaces de Usuario 16

Podemos depurar para ver las hebras

Proceso del sistema

Nuestro proceso1. Click – Selecciono proceso

2. Depurar

3. Depurar hebras

4. Ver hebras (actualizar)

Interfaces de Usuario 17

Nuestra hebra

UI Thread

Interfaces de Usuario 18

Análisis

● ¿Cuánto vive la hebra?– Termina cuando termina el método run(). Puede

terminar más tarde que la Actividad / Servicio que lo inició → No debería tener referencias a estos objetos, puede darnos problemas

● Es una 'mala solución' – No podemos indicar en la interfaz que hemos terminado

● ¿Qué pasa si damos muchas veces al botón? → Generamos muchas hebras...

Interfaces de Usuario 19

Soluciones

● Problemas para actualizar UI desde la hebra– Creamos varias hebras (la UI y otras) y las

comunicamos: Handler

● Problemas si piden muchas hebras– Creamos un 'pool' de hebras y sólo tenemos

ese número activo– Así además reutilizamos las hebras y no hace

falta crearlas cada vez: ThreadPoolExecutor

Interfaces de Usuario 20

Ejecución multihebra

● Separamos tareas 'que tardan mucho' en diferentes hebras

● Así, simulamos mayor paralelismo, y la interfaz responde sin penalizaciones

● Casos normales de una hebra:– Un servicio de actualización que se ejecuta de

fondo (background) – Un calculo que lleva mucho tiempo– Almacenamiento de datos en tarjeta SD

Interfaces de Usuario 21

¿Cómo programamos esto en Android?

● Definiendo un servicio que se ejecuta de fondo y envía notificaciones a la interfaz (lo veremos, es la 'opción mejor')

● Usando una hebra (thread) de fondo– Usando la clase Thread y Handler directamente

• Las hebras no pueden notificar directamente a la hebra de interfaz UI

– Usando la clase AsyncTask, que facilita ejecutar tareas de fondo y publicar resultados en la hebra UI principal

Interfaces de Usuario 22

Hebras

● En Android, tenemos una hebra principal, la UIThread, que es responsable de la interfaz

● Esta hebra puede crear otras hebras secundarias que NO pueden acceder a la interfaz

● La comunicación entre la hebra ppal y las secundarias se hace con un Handler

Interfaces de Usuario 23

Handler

● Al comunicarnos con la hebra principal con un Handler, podemos hacer dos cosas:– Intercambiar mensajes de la cola de mensajes

del Handler– Pasar objetos Runnables para que los ejecute

la hebra principal

http://developer.android.com/reference/android/os/Handler.html

Interfaces de Usuario 24

Comunicación hebras Mensajes

<<Thread>>Hebra principal (UI)

Handler h

<<Thread>>Hebra secundaria 1

<<Thread>>Hebra secundaria 1

1. Message msg = h.obtainMessage()

2. h.sendMessage(msg)

handleMessage(Message msg)

Constructor con patrón de diseño

Factoría para reutilizar objetos

Interfaces de Usuario 25

Esquema paso mensajes

HebraPrincipal extends Activity {private Handler h = new Handler() {public void handleMessage(Message msg) {

// procesa mensajes}

metodo() { // crea una hebra secundaria Thread th = new Thread(new Runnable(){ // método de la hebra secundaria ... Message msg = h.obtainMessage(); h.sendMessage(msg); ... }); } }

Interfaces de Usuario 26

Comunicación hebrasCola de Tareas

<<Thread>>Hebra principal (UI)

Handler h

<<Thread>>Hebra secundaria 1

<<Thread>>Hebra secundaria 1

<<Runnable>>Runnable r2

h.post(r1)

h.postAtFrontOfQueue(r2)

<<Runnable>>Runnable r1

Interfaces de Usuario 27

Esquema paso tareasHebraPrincipal extends Activity {

private Handler h = new Handler() {public void onCreate() {

…Thread th = new Thread(r2, “Background”);th.start();

}private Runnable r1 = new Runnable() {

public void run() {// actualizo UI

}}private Runnable r2 = new Runnable() {

public void run() {// ejecuto cosash.post(r1);

}}

}

Interfaces de Usuario 28

Más detalle

Sólo el thread principal tiene un objeto Looper, a través del que

accede a la cola de mensajes en un bucle

Interfaces de Usuario 29

Ejemplo con mensajes

● Vamos a hacer una aplicación que vaya mostrando el progreso de la tarea de fondo

● Usaremos ProgressBar

Interfaces de Usuario 30

Interfaz main.xml (I)

Interfaces de Usuario 31

Interfaz main.xml (II)

Interfaces de Usuario 32

Actividad (I)

Interfaces de Usuario 33

Actividad (II)

Interfaces de Usuario 34

Actividad (III)

Interfaces de Usuario 35

Ejecución

Interfaces de Usuario 36

Ejemplo paso de tareas

Interfaces de Usuario 37

main.xml

Interfaces de Usuario 38

Actividad (I)

Interfaces de Usuario 39

Actividad (II)

Interfaces de Usuario 40

Actividad (III)

Interfaces de Usuario 41

Usando AsyncTask

● Usar las hebras directamente es tedioso

● Android proporciona AsyncTask– Permite crear una hebra de fondo que publica

en la hebra UI sin tener que programar Threads o Handlers

– Definimos una tarea 'asíncrona' que se ejecuta de fondo y publica sus resultados en la hebra UI

Interfaces de Usuario 42

AsyncTask – Uso básico● Hebras: UI Thread (UITh) y Background Thread

(BGTh, la AsyncTask) ●Tipos genéricos: Params, Progress, Result● Estados principales

– onPreExecute (UITh)– doInBackground (BGTh)– onProgressUpdate(UITh)– onPostExecutre(UITh)

● Método auxiliar– publishProgress (BGTh)

Interfaces de Usuario 43

AsyncTask

● Una AsyncTask tiene 3 tipos genéricos● AsyncTask<Params, Progress, Result>

– Params – tipo de parámetros enviados a la tarea para su ejecución

– Progress – tipo de las unidades de progreso publicadas durante su ejecución

– Result – resultado de la ejecución de la tarea

● Si no usamos un tipo, lo ponemos Void (con V)

Interfaces de Usuario 44

Métodos de AsyncTask● onPreExecute(): invocado por UIth

justo tras ejecutar la tarea

● doInBackground(Params) – invocado por BGTh justo tras onPreExecute

● onProgressUpdate(Progress) – invocado por UITh tras una llamada de BGTh a publishProgress(Progress)

● onPostExecute(Result) invocado por UITh justo tras terminar BGTh

Interfaces de Usuario 45

Ejemplo AsyncTask

Interfaces de Usuario 46

Interfaz main.xml

Interfaces de Usuario 47

Actividad MainTask

Interfaces de Usuario 48

Actividad MainTask (II)

… → número de argumentos

variable, se procesa como un array

Interfaces de Usuario 49

Actividad MainTask (III)

Interfaces de Usuario 50

Yamba. StatusActivity2 (I)

Interfaces de Usuario 51

StatusActivity2 (I)

Interfaces de Usuario 52

Retoques finales

● Ya tenemos la aplicación

● Podemos– Añadir que descuente el

número de caracteres– Añadir colores/imágenes

Interfaces de Usuario 53

ContarCaracteres main.xml

Interfaces de Usuario 54

ContarCaracteres -TextWatcher (I)

Interfaces de Usuario 55

ContarCaracteres -TextChangedListener (III)

Interfaces de Usuario 56

Personalización

●En Android en res podemos hacer carpetas con recursos para– Una orientación res/layout-land/status.xml– Un idioma res/values-es-rES/strings.xml

(language-region)

●En eclipse new->XML File

Interfaces de Usuario 57

Asistente recursos alternativos

Interfaces de Usuario 58

Lo que llevamos hecho...

Interfaces de Usuario 59

Resumen

● En este tema hemos aprendido a gestionar concurrencia con tareas de fondo en Android

● Hemos visto cómo gestionar directamente hebras, comunicarlas con Handlers, y cómo usar AsyncTasks

● Por último, cómo darle un mejor aspecto visual y crear recursos alternativos

Interfaces de Usuario 60

¿Preguntas?