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
- Primero que nada necesitamos el permiso para acceder a internet
- El servicio con el que vamos a trabajar es una lista de productos, con lo que vamos a necesitar un clase que los represente.
- 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
Android Avanzando - Clase 02
By Ing. Sebastian M. Irazabal
Android Avanzando - Clase 02
- 775