CLASE 02

Manejo de Hilos

Hilo Principal (UI Thread)

El hilo principal o UI thread en inglés (Hilo de Interfaz de Usuario) es el encargado de manejar todas las vistas. No se deben realizar cálculos muy extensos ni tareas que puedn bloquear su ejecución ya que ello llevaría a que el hilo principal nos muestre un cartel como el siguiente, llamado ANR

Forzar ANR

Simplemente vamos a hacer un calculo pesado, como son los factoriales en el Hilo Principal. Creamos un boton y al clickearlo forzamos el ANR

int factorial = 0;
int sumaFactoriales = 0;
for (int i=0; i<60000; i++){
    factorial = 1;
    for (int j=1; j<i; j++){
        factorial = factorial * j;
    }
    sumaFactoriales += factorial;
}
Toast.makeText(getApplicationContext(), 
    "La suma de factoriales de 1 a 60000 es :" + sumaFactoriales,
    Toast.LENGTH_LONG).show();

Y si ponemos botones para cambiar el color de fondo, vamos a ver que los mismos no responden porque está esperando terminar el cálculo.

Métodos para evitar ANR

 

  • Thread + Handler
  • AsyncTask

 

Nosotros nos vamos a centrar en el AsyncTask, que es una de las formas más utilizadas, por su versatilidad. permite realizar tareas de manera asincrónica, y tiene su propio ciclo de vida.

AsyncTask

Para implementar un AsyncTask, debemos crear una clase que extienda justamente de AsyncTask. La sintaxis es la siguiente:

private class tareaFactorial extends AsyncTask <Void, Void, Integer>

Los parámetros van entre <>, porque son tipos genéricos (como cuando creamos una lista). Y los mismos son:

  • Parámetros de ingreso
  • Parámetro de progreso
  • Parámetro de retorno

Métodos de AsyncTask

Toda AsyncTask debe tener al menos un método, llamado doInBackground() que es justamente la tarea de segundo plano que queremos ejecutar.

También podemos usar un constructor para pasar información adicional y el método onPostExecute() que como su nombre lo indica se ejecuta justamente al finalizar la ejecución en segundo plano. Tiene la particularidad de que dicho método se ejecuta sobre el UI Thread, lo que nos permite accionar sobre la interfaz de usuario.

Hay otros metodos también, como el onPreExecute y onProgressUpdate

Loadings

Muchas veces, resulta útil y necesario, informar la usuario sobre el trabajo que se está haciendo en segundo plano, justamente para informarle que debe aguardar a que un proceso se complete. No siempre es necesario, hay veces en las que podemos hacer estas tareas en segundo plano sin que el usuario lo sepa explícitamente, pero en otros casos, sí resulta indispensable hacerlo.

Para ello, nos vamos a incorporar un método más como el onPreExecute, para realizar los preparativos del progreso antes de que inicie la tarea.

Loadings

Hay 2 formas de llevar a cabo el progreso

  • Una es incorporando  un elemento de progreso en el layout, que esté siempre oculto y mostrarlo sólo mientras se esté ejecutando la tarea

 

  • Y la otra, que a mi me gusta más y me parece más prolija a nivel de código, es crear un diálogo de progreso en tiempo de ejecución
progress = new ProgressDialog(context);
progress.setTitle(context.getString(R.string.progress_title));
progress.setMessage(context.getString(R.string.progress_msg));
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.show();

WEB SERVICES

Web Service

Como su nombre lo indica los Web Services, son Servicios Web que hoy en día utilizan casi todas las aplicaciones para nutrirse de información.

Un Cliente, en este caso nuestra aplicación le envía una petición (o Request) al Servidor, el cuál emite una respuesta (o Response).

 

Los más populares son los servicios REST que se manejan con respuestas en formato JSON

REST + JSON

REST significa REpresentational State Transfer y es una arquitectura que no tiene estado, lo cual significa que entre 2 llamados nos va a devolver siempre la misma información. Con lo cual no le podemos pedir que recuerde datos como ser USER y PASS y se lo debemos enviar en cada consulta.

 

JSON viene de JavaScript Object Notatio, es justamente una forma de representación de objetos, en formato de texto plano

Consumir Servicio REST

Los pasos a seguir para consumir un servicio REST son los siguientes

 

  1. Primero que nada necesitamos el permiso para acceder a internet
  2. El servicio con el que vamos a trabajar es una lista de productos, con lo que vamos a necesitar un clase que los represente.
  3. Una tarea para consumir el servicio

 

Consumir Servicio REST

El permiso para acceder a internet es:

<uses-permission android:name="android.permission.INTERNET"/>

Luego, vamos a crear una clase con los campos:

  • id
  • description
  • image
  • price

 

Es fundamental que usemos estos nombres porque son los mismos nombres que tiene el objeto JSON que nos devuelve el servicio

Consumir Servicio REST

El servicio que vamos a usar es:

http://sebasira.com.ar/cursos/android-avanzado/ferreteria.php

 

Este servicio nos devuelve un objeto JSON, y para transformar el mismo en un objeto JAVA vamos a usar una libreria de Google, llamada GSON. Para ellos agregamos al gradle:

compile 'com.google.code.gson:gson:2.5'

Esta librería requiere que los campos de  la clase de JAVA se llamen igual que los del objeto JSON y tengan sus getters y setters

Consumir Servicio REST

Vamos a necesitar otras librerías para manejar la conexion:

compile 'com.android.volley:volley:1.0.0'

Volley es una libreria mantenida por la gente de Android y es lo que oficialmente recomiendan utilizar para el manejo de las peticiones Web.

 

Esta librería, requiere que primero inicialicemos una cola de consultas.

Consumir Servicio REST

JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {

    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        // TODO Auto-generated method stub

    }
});

Y luego podemos crear nuestra petición que ya maneja de manera automatica la ejecución en 2do plano, y las respuestas corren en el Hilo Principal.

requestQueue = Volley.newRequestQueue(getApplicationContext());

Consumir Servicio REST

requestQueue.add(jsObjRequest);

En este caso la consulta que hacemos un GET a la URL que antes mencionamos (seteando el id de producto) y que nos va a responder con un ObjetoJSON.

 

Luego de creada la request, para que  la misma se ejecute, debe ser añadida a la cola que inicializamos anteriormente:

Cargar Imagen de URL

Supongamos que ahora queremos mostrar la imagen, no solo ver la URL de la misma. Lo que deberíamos hacer, al igual que como hicimos con el producto, es ir a buscarla de manera asíncrona, y mostrarla cuando se haya descargado por completo. Por suerte para nosotros, hay una librería muy popular que nos resuleve este asunto para las imágenes.

Se llama Universal Image Loader, y para usarla la agregamos al gradle:

compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'

Cargar Imagen de URL

Primero la inicializamos en el onCreate:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.
    Builder(this).build();
ImageLoader.getInstance().init(config);

Y luego cargamos la imagen:

ImageLoader.getInstance().displayImage(producto.getImage(), imageView);

Gracias!

No dejen de consultar cualquier duda que surja

sebasira@gmail.com

Made with Slides.com