Uso de Hilos y tareas asíncronas(AsyncTask) en Android

Hilos y AsyncTasks en Android
Este artículo ha sido creado con el fin de presentarte los beneficios del uso de hilos en tus aplicaciones Android. La idea es evaluar entre varias opciones la mejor alternativa para implementar concurrencia entre las tareas que se ejecutan. Esta valoración mantendrá la sensación multitarea, evitará bloqueos y optimizará el hilo principal de tus proyectos.

CONTENIDO

El Manejo de Hilos en Android

Ejemplo de Hilos: Ordenar Números con el Algoritmo Burbuja

Experimento #1: Ordenar números sin Hilos en Java

Experimento #2: Usar Hilos en Java para ordenar los números

Experimento #3: Usar AsyncTasks en Android

Experimento #4: Retener una AsyncTask ante la Rotación de la Pantalla

Conclusiones

El Manejo de Hilos en Android

Un hilo es una unidad de ejecución asociada a una aplicación. Es la estructura de la programación concurrente, la cual tiene como objetivo dar la percepción al usuario que el sistema que ejecuta realiza múltiples tareas a la vez.

Aunque los hilos se benefician de las tecnologías multinucleos y multiprocesamiento, no significa que una arquitectura simplista no se beneficie de la creación de hilos.

Cuando se construye una aplicación Android, todos los componentes y tareas son introducidos en el hilo principal o hilo de UI (UI Thread). Hasta el momento hemos trabajado de esta forma, ya que las operaciones que hemos realizado toman poco tiempo y no muestran problemas significativos de rendimiento visual en nuestros ejemplos. Pero en tus proyectos reales no puedes pretender que todas las acciones que lleva a cabo tu aplicación sean simples y concisas.

En ocasiones hay instrucciones que toman unos segundos en terminarse, esta es una de las mayores causas de la terminación abrupta de las aplicaciones. Android está diseñado para ofrecerle al usuario la opción de terminar aquellas aplicaciones que demoran más de 5 segundos en responder a los eventos del usuario. Cuando esto pasa, podemos ver el famoso Diálogo ANR (Application not respond).

Diálogo ANR de Android
¿Qué pasaría si intentas cargar una imagen jpg de 3MB desde un servidor externo via HTTP en tu aplicación?, si la conexión es rápida, tal vez nada. Pero para conexiones lentas esto tomara algunos segundos. ¿Crees que se vería muy bien, que tu aplicación se dedique a cargar primero la imagen y luego actualice la interfaz de usuario?

¡En lo absoluto!, esto arruina la fluidez visual y estropea la estadía de nuestros usuarios, lo que en la mayoría de casos termina en la eliminación de tu aplicación. A nivel computacional este caso podría apreciarse de la siguiente forma:

La imagen ilustra la transición de las tareas que ocurren en el hilo principal de la aplicación. Si tu tarea toma algunos segundos se arruinaría la capacidad de respuesta, ya las tareas están en serie, es decir, hasta que una no acabe la otra no puede iniciar.

El camino correcto es renderizar la interfaz de la aplicación y al mismo tiempo ejecutar en segundo plano la otra actividad para continuar con la armonía de la aplicación y evitar paradas inesperadas. Es aquí donde entran los hilos, porque son los únicos que tienen la habilidad especial de permitir al programador generar concurrencia en sus aplicaciones y la sensación de multitareas ante el usuario. Esta técnica es mostrada en el siguiente gráfico:

Uso de Hilos en Android
Se ha creado un nuevo hilo donde se ejecuta la tarea en el mismo intervalo de tiempo [t1, t2], pero esta vez el tiempo de ejecución de la tercera tarea UI se extendió debido a que se realizarán pequeños incrementos entre al segundo y tercera tarea. Aunque el tiempo empleado es el mismo, la respuesta ante el usuario simula una aplicación limpia.

Recuerda que existen dos tipos de procesamientos de tareas, Concurrencia y Paralelismo. La concurrencia se refiere a la existencia de múltiples tareas que se realizan simultáneamente compartiendo recursos de procesamiento. Y paralelismo es la ejecución de varias tareas al tiempo en distintas unidades de procesamiento, por lo que es mucho mas rápido que la concurrencia.

Ejemplo de Hilos: Ordenar Números con el Algoritmo Burbuja

Este tutorial no tendría gran valor si no encontrases un buen ejemplo explicativo. Por esta razón verás la construcción de una aplicación llamada AsyncLab. Dicha aplicación tiene como fin mostrar algunos experimentos de ejecución del Algoritmo de Ordenamiento Burbuja Simple, con 4 diferentes caminos y así evaluar la mejor opción.

Puedes obtener el proyecto completo en el siguiente enlace:

Descargar CódigoEn cuanto a diseño, AsyncLab consiste en una actividad Main que despliega un menú construido a través de una lista. Cada uno de los ítems representa un experimento aislado que muestra al usuario el comportamiento que se produce. Precisamente ese comportamiento es mostrado en una segunda actividad hija llamada ABTest, donde existe el botón sortButton para iniciar el ordenamiento de los números y cancelButton para cancelar la operación.

Experimento #1: Ordenar números sin Hilos en Java

Para este experimento se debe aclarar que cada ítem de la actividad Main es dirigido a la misma actividad ABTest, es decir, no se creó una actividad o fragmento para cada uno. Lo que se hizo fue establecer una condición dentro del método onClick() del botón "Ordenar".

Veamos:

public void onClickSort(View v) {
switch (position){
case 0:
// Experimento #1
break;
case 1:
// Experimento #2
break;
case 2:
// Experimento #3
break;
case 3:
// Experimento #4
break;
}
}

Un programador que desconozca la existencia de la programación concurrente y el uso de hilos en Java, abordaría una solución simplista para ordenar los números. Se le ocurría crear un procedimiento para representar el algoritmo burbuja y lo usaría directamente cuando el botón de ordenamiento sea pulsado. Luego mostraría un Toast para indicarle al usuario que la tarea se ha llevado a cabo.

public void onClickSort(View v) {
switch (position){
case 0:
bubbleSort(numbers);
Toast.makeText(
getBaseContext(),
"¡Números Ordenados!",
Toast.LENGTH_LONG).show();
break;
...
}
private void bubbleSort(int[] numbers) {
int aux;
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = 0; j < numbers.length -1; j++) {
if (numbers[j] > numbers[j+1])
{
aux = numbers[j];
numbers[j] = numbers[j+1];
numbers[j+1] = aux;
}
}
}
}

Este enfoque es completamente válido y funcional hasta cierto punto. Recuerda que el algoritmo de ordenamiento burbuja puede llegar a tener un orden de complejidad de O(N2) dependiendo de la dispersión de los números. Esto significa que si en algún momento la cantidad de números requiere una cantidad de segundos considerable, el usuario debe esperar a que se termine la ejecución del algoritmo antes de poder interactuar de nuevo con la aplicación.

Bloqueo del hilo principal de una aplicación Android
Al ejecutar este experimento el botón "Ordenar" queda seleccionado y la interfaz se congela. Si das taps prolongadamente, para intentar que la aplicación responda, obtendrás un diálogo ANR.

Experimento #2: Usar Hilos en Java para ordenar los números

Si recuerdas la época en que veías tus clases de Java en el instituto, se usaba el paquete java.util.concurrent para acceder a la clase Thread que es la que representa un hilo. También has de recordar que un hilo ejecuta las instrucciones que se implementan el método run() de la interfaz Runnable. Y que para activar estas sentencias se ha de invocar al método start() para iniciar la ejecución.

Aplicando esta definición puedes crear un método que construya un hilo para añadir la ejecución del método bubbleSort():

public void onClickSort(View v) {
switch (position){
...
case 1:
execWithThread();
break;
...
}
public void execWithThread(){
new Thread(
new Runnable() {
@Override
public void run() {
bubbleSort(numbers);
Toast.makeText(
getBaseContext(),
"¡Números Ordenados!",
Toast.LENGTH_LONG).show();
}
}
).start();
}

Aunque el código anterior parece correcto, al iniciar este experimento obtendrás un error debido a que no es aceptada la creación de instancias de la clase Toast dentro de un Hilo. La documentación de Android recomienda no acceder directamente a los objetos del hilo de UI desde los hilos creados manualmente. Advierten que pueden llegar a producirse anomalías debido a la ausencia de sincronización.

Para evitar acceder directamente sobre los elementos de la UI, puedes usar algunos de los siguientes métodos: Activity.runOnUiThread(), View.post(Runnable) y View.postDelayed(Runnable, long). Estos nos permitirán presentar la información necesaria que se ha procesada en UI Thread.

runOnUiThread() es ideal para presentar resultados en el UI Thread cuando se ejecutan sentencias generales asociadas a una actividad. El método post() se usa para relacionar un hilo al contenido de un View específico. postDelayed() realiza exactamente lo mismo que post(), solo que retrasa n milisegundos el inicio del hilo.

El ejemplo anterior quedaría asegurado con la siguiente definición:

public void execWithThread(){
new Thread(
new Runnable() {
@Override
public void run() {
bubbleSort(numbers);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(
getBaseContext(),
"¡Números Ordenados!",
Toast.LENGTH_LONG).show();
}
});
}
}
).start();
}

Hacemos exactamente lo mismo pero esta vez asignamos ejecutamos el método makeText() del de runOnUiThread() junto a una nueva instancia Runnable que comunique las acciones al hilo principal. Internamente esta operación entra a un proceso de cola de peticiones, donde el main Thread gestionará el momento adecuado para iniciarla.

Experimento #3: Usar AsyncTasks en Android

Existen casos en los que se ejecutan varias instrucciones que deben presentar cambios en el hilo principal. Si se aplica el enfoque visto en la sección anterior el código para el envío de las ejecuciones tiende a ser muy largo, confuso y poco maleable a la hora de mantenimiento.

Por esta razón ha sido creada la interfaz AsyncTask, cuyo objetivo es liberar al programador del uso de hilos, la sincronización entre ellos y la presentación de resultados en el hilo primario. Esta clase unifica los aspectos relacionados que se realizarán en segundo plano y además gestiona de forma asíncrona la ejecución de las tareas.

Para implementarla debes extender una nueva clase con las características de AsyncTask e implementar los métodos correspondientes para la ejecución en segundo plano y la publicación de resultados en el UI Thread. Adaptemos el ejemplo anterior a esta filosofía:

private class SimpleTask extends AsyncTask<Void, Integer, Void> {

Se hace visible el botón "Cancelar" y se desactiva
el botón "Ordenar"

@Override
protected void onPreExecute() {
cancelButton.setVisibility(View.VISIBLE);
sortButton.setEnabled(false);
}

Ejecución del ordenamiento y transmision de progreso

@Override
protected Void doInBackground(Void... params) {
int aux;
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = 0; j < numbers.length -1; j++) {
if (numbers[j] > numbers[j+1])
{
aux = numbers[j];
numbers[j] = numbers[j+1];
numbers[j+1] = aux;
}
}
// Notifica a onProgressUpdate() del progreso actual
if(!isCancelled())
publishProgress((int)(((i+1)/(float)(numbers.length-1))*100));
else break;
}
return null;
}

Se informa en progressLabel que se canceló la tarea y
se hace invisile el botón "Cancelar"

@Override
protected void onCancelled() {
super.onCancelled();
progressLabel.setText("En la Espera");
cancelButton.setVisibility(View.INVISIBLE);
sortButton.setEnabled(true);
}

Impresión del progreso en tiempo real

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressLabel.setText(values[0] + "%");
}

Se notifica que se completó el ordenamiento y se habilita
de nuevo el botón "Ordenar"

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
progressLabel.setText("Completado");
sortButton.setEnabled(true);
}
}

SimpleTask se extiende de AsyncTask que además de ser abstracta es genérica. Las tres variables de entrada que posee se refieren a los Parámetros, Unidades de Progreso y Resultados respectivamente.

La clase AsyncTask posee métodos te permitirán coordinar la ejecución de las tareas que deseas ubicar en segundo plano. Estos métodos tienen los siguientes propósitos:

onPreExecute(): En este método van todas aquellas instrucciones que se ejecutarán antes de iniciar la tarea en segundo plano. Normalmente es la inicialización de variables, objetos y la preparación de componentes de la interfaz.

doInBackground(Parámetros...): Recibe los parámetros de entrada para ejecutar las instrucciones especificas que irán en segundo plano, luego de que ha terminado onPreExecute(). Dentro de él podemos invocar un método auxiliar llamado publishProgress(), el cual transmitirá unidades de progreso al hilo principal. Estas unidades miden cuanto tiempo falta para terminar la tarea, de acuerdo a la velocidad y prioridad que se está ejecutando.

onProgressUpdate(Progreso...): Este método se ejecuta en el hilo de UI luego de que publishProgress() ha sido llamado. Su ejecución se prolongará lo necesario hasta que la tarea en segundo plano haya sido terminada. Recibe las unidades de progreso, así que podemos usar algún View para mostrarlas al usuario para que este sea consciente de la cantidad de tiempo que debe esperar.

onPostExecute(Resultados...): Aquí puedes publicar todos los resultados retornados por doInBackground() hacia el hilo principal.

onCancelled(): Ejecuta las instrucciones que desees que se realicen al cancelar la tarea asíncrona.Comprendiendo estas propiedades, la clase SimpleTask queda fácil de asimilar. Si observas onPreExecute(), se comienza por hacer visible el botón cancelButton ( ya que solo aparece cuando la tarea asíncrona está en ejecución) y luego se desactiva el botón sortButton para evitar la ejecución la actividad un sinnúmero de ocasiones.

@Override
protected void onPreExecute() {
cancelButton.setVisibility(View.VISIBLE);
sortButton.setEnabled(false);
}

En el caso de doInBackground() se han puesto parámetros de tipo Void, ya que no se recibe valores de entrada y solo se ejecutarán las instrucciones del ordenamiento burbuja. Si eres buen observador, el método publishProgress() aparece al finalizar el primer bucle for. Esto con el fin de obtener una medida relativa en tiempo real del progreso actual. Matemáticas básicas!

El tipo de dato para las unidades de progreso es Integer, así se obtienen números enteros que muestren un porcentaje entre el intervalo [0, 100]. Dicha medida se muestra en un TextView llamado progressLabel.

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressLabel.setText(values[0] + "%");
}

En onPostExecute() se recibe un tipo Void como resultado, debido a que no se recibe retorno de doInBackground(). Aquí aprovecharás para restablecer sortButton y cancelButton a su estado inicial. También puedes avisar a través de progressLabel que se ha completado el trabajo.

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
progressLabel.setText("Completado");
cancelButton.setVisibility(View.INVISIBLE);
sortButton.setEnabled(true);
}

Ahora solo queda usar el método execute() para comenzar a ejecutar la tarea asíncrona en el método onClick():

public void onClickSort(View v) {
switch (position){
...
case 2:
execWithAsyncTask();
break;
...
}
public void execWithAsyncTask(){
simpleTask= new SimpleTask();
simpleTask.execute();
}

Las Tareas Asíncronas deben ser creadas, cargadas y ejecutadas dentro del UI Thread para su correcto funcionamiento.

Progreso de una Tarea Asíncrona en Android
Cancelar una tarea Asíncrona

Puedes detener la ejecución de una tarea asíncrona usando el método cancel(). Este invoca el método onCancelled(), en vez de doInBackground(), por lo que se descartarán los resultados que estén por entregarse al hilo principal. Si necesitas saber el momento exacto en que terminó la tarea, puedes comprobar el valor arrojado por el método isCancelled()(que retorna en true si ya se ha cancelado):

En AsyncLab la tarea asíncrona se cancela en el método onClick() con cancelButton.

public void onClickCancel(View v){
simpleTask.cancel(true);
}

Como viste en la definición de SimpleTask, onCancelled() se sobrescribe para que ya no muestre unidades de progreso en progressLabel y para restablecer los estados de los botones:

@Override
protected void onCancelled() {
super.onCancelled();
progressLabel.setText("En la Espera");
cancelButton.setVisibility(View.INVISIBLE);
sortButton.setEnabled(true);
}

Complementariamente se coordina la detención del ordenamiento burbuja con un break si en algún momento la actividad se ha cancelado:

if(!isCancelled())
publishProgress((int)(((i+1)/(float)(numbers.length-1))*100));
else break;

Experimento #4: Retener una AsyncTask ante la Rotación de la Pantalla

Hasta el momento nuestra tarea asíncrona ejecuta el ordenamiento de los números de forma perfecta, pero...¿que pasará si rotas la pantalla mientras se esta ordenando?

¿Lo has probado?... desafortunadamente la tarea asíncrona es alterada y la ejecución de onProgressUpdate() es anulada. Esto se debe a que cuando hay un cambio de configuración en tus aplicaciones( rotación de la pantalla, cambio de idioma, cambio de teclado) las actividades llaman a su método onDestroy() y luego a su método onCreate() para actualizar su layout y recursos. Lo que quiere decir que comienza un nuevo ciclo de vida para la actividad y por ende el hilo principal toma otro rumbo.

Lee también Ciclo de Vida de una Actividad en Android

Para solucionar este pequeño inconveniente se usará el método setRetainInstace(), el cual permite retener las características de un fragmento ante un cambio de configuración. En consecuencia crearemos un fragmento personalizado, donde se añada una instancia de la tarea asíncrona ProgressBarTask con el fin de que el fragmento la proteja ante el cambio de configuración.

Lee También Fragmentos en una Aplicación Android

Cabe añadir que para el progreso de la tarea usaremos una ProgressBar en vez de progressLabel, pero básicamente el comportamiento es igual a SimpleTask.

public class HiddenFragment extends Fragment {

Interfaz para la comunicación con la actividad ABTest.

static interface TaskCallbacks {
void onPreExecute();
void onProgressUpdate(int progress);
void onCancelled();
void onPostExecute();
}
private TaskCallbacks mCallbacks;
ProgressBarTask progressBarTask;
public HiddenFragment() {}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
//Obtener la instancia de ABTest
mCallbacks = (TaskCallbacks) activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Retener el fragmento creado
setRetainInstance(true);
//Una vez creado el fragmento se inicia la tarea asincrona
progressBarTask = new ProgressBarTask();
progressBarTask.execute();
}
@Override
public void onDetach(){
super.onDetach();
mCallbacks = null;
}
public class ProgressBarTask extends AsyncTask<Void, Integer, Long> {
@Override
protected void onPreExecute() {
if (mCallbacks != null) {
mCallbacks.onPreExecute();
}
}
@Override
protected Long doInBackground(Void... params) {
long t0 = System.currentTimeMillis();
int aux;
int numbers[] = ABTest.numbers;
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = 0; j < numbers.length -1; j++) {
if (numbers[j] > numbers[j+1])
{
aux = numbers[j];
numbers[j] = numbers[j+1];
numbers[j+1] = aux;
}
}
if(!isCancelled())
publishProgress((int)(((i+1)/(float)(numbers.length-1))*100));
else break;
}
return t0;
}
@Override
protected void onProgressUpdate(Integer... values) {
if (mCallbacks != null) {
mCallbacks.onProgressUpdate(values[0]);
}
}
@Override
protected void onPostExecute(Long aLong) {
if (mCallbacks != null) {
mCallbacks.onPostExecute();
}
}
}
}

Se le ha llamado HiddenFragment porque no posee interfaz de usuario( por eso su método onCreateView() no está sobrescrito). Su estructura está formada por una interfaz llamada TaskCallbacks que le permitirá comunicarse con la actividad ABTest, donde se han añadido 4 métodos de comunicación para sobrescribir respectivamente los métodos callback de la clase ProgressBarTask.

Recuerda que para que la comunicación se dé, es necesario obtener la instancia de la actividad ABTest en el método onAttach(). Una vez realizado esto, es posible comenzar a llamar todas las implementaciones de los métodos de la interfaz que han sido definidos en la actividad. Es de vital importancia que ejecutes la tarea en el método onCreate() del fragmento para arraigarla con setRetainInstance().

Al implementar la interfaz TaskCallbacks en ABTest es necesario sobrescribir los métodos de la siguiente forma:

@Override
public void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
cancelButton.setVisibility(View.VISIBLE);
sortButton.setEnabled(false);
}
@Override
public void onProgressUpdate(int progress) {
progressBar.setProgress(progress);
progressLabel.setText(progress+"%");
}
@Override
public void onCancelled() {
progressBar.setVisibility(View.INVISIBLE);
cancelButton.setVisibility(View.INVISIBLE);
progressLabel.setText("En la Espera");
sortButton.setEnabled(true);
}
@Override
public void onPostExecute() {
progressBar.setVisibility(View.INVISIBLE);
cancelButton.setVisibility(View.INVISIBLE);
progressLabel.setText("Completado");
sortButton.setEnabled(true);
}

Básicamente se oculta la ProgressBar al igual que se hacía con la progressLabel y luego configuras los botones, para que aparezcan en la situación adecuada. También se usa el método setProgress() para actualizar el estado de realización de la tarea.

A continuación crea el fragmento justo cuando sea presionado sortButton para que la tarea se inicie.

private void execWithProgresBar() {
FragmentManager fg = getFragmentManager();
fragment = new HiddenFragment();
FragmentTransaction transaction = fg.beginTransaction();
transaction.add(fragment, HIDDEN_FRAGMENT_TAG);
transaction.commit();
}

Finalmente asegura que los botones y la barra se restablezcan correctamente en el método onCreate() de ABTest cuando surja la rotación de la pantalla:

fragment = (HiddenFragment)getFragmentManager().
findFragmentByTag(HIDDEN_FRAGMENT_TAG);
if(position==3 && fragment!=null) {
if(fragment.progressBarTask.getStatus()== AsyncTask.Status.RUNNING){
progressBar.setVisibility(View.VISIBLE);
cancelButton.setVisibility(View.VISIBLE);
sortButton.setEnabled(false);
}
}

En castellano, el código anterior se traduce a "Si se ha elegido la opción 3 y el fragmento ya ha sido creado, entonces compruebe si la tarea está en ejecución. Si es así, entonces mantener visible la barra de progreso, mantener visible el botón de cancelar y además conservar el estado de inactividad de sortButton". Supongo que ya deduces que getStatus() obtiene el estado actual de la tarea y que RUNNING es un tipo enumerado que representa el estado de ejecución.

Ahora prueba el experimento y verás como al cambiar a landscape, la ProgressBar y la tarea asíncrona siguen intactas.

Aplicación Android con una ProgressBar en Landscape
Conclusiones

No hace falta justificar ampliamente el porqué es mejor usar la clase AsyncTask para gestionar hilos y trabajos en segundo plano. Este mecanismo permite optimizar tanto el flujo de tus aplicaciones como el orden de codificación de las Actividades. Así que la próxima vez que debas poner en ejecución una operación que requiere algunos segundos considerables, no dudes en acudir a las tareas asíncronas.

Icono de la Aplicación AsyncLab cortesía de IconFinder

James Revelo Urrea - Desarrollador independiente http://www.hermosaprogramacion.com

Fuente: este post proviene de Hermosa Programación, donde puedes consultar el contenido original.
¿Vulnera este post tus derechos? Pincha aquí.
Creado:
¿Qué te ha parecido esta idea?

Esta idea proviene de:

Y estas son sus últimas ideas publicadas:

Recomendamos

Relacionado

informática desarrollo android

¿Quieres cargar más elementos en tu lista usando un indicador de actividad circular que muestran muchas otras aplicaciones Android? Entonces este tutorial es para ti, ya que te enseñará a usar el patrón de diseño "Swipe to Refresh", el cual refresca el contenido de una view con tan solo arrastrar verticalmente la interfaz. Para comprender este tema crearemos una pequeña aplicación llam ...

informática desarrollo android

Las listas en Android son contenedores supremamente útiles para organizar información en forma vertical y con la capacidad de usar scrolling(desplazamiento) para simplificar su visualización. Esta técnica es muy popular en muchas aplicaciones, ya que permite mostrarle al usuario un conjunto de datos de forma practica y accesible. Si sigues leyendo podrás aprender sobre: La clase ListView Crear un ...

informática desarrollo android

Este artículo te explicará el uso del Navigation Drawer en Android para crear una navegación a través de un Menú deslizante. Verás como implementar un Drawer Layout para el diseño. Aprenderás a manejar los eventos relacionados. Y también a complementar su funcionamiento con la action bar mediante un Action Bar Drawer Toggle. CONTENIDO ¿Cómo crear un menú deslizante con un Navigation Drawer? Ejem ...

informática desarrollo android

Las listas en Android son contenedores supremamente útiles para organizar información en forma vertical y con la capacidad de usar scrolling(desplazamiento) para simplificar su visualización. Esta técnica es muy popular en muchas aplicaciones, ya que permite mostrarle al usuario un conjunto de datos de forma practica y accesible. Si sigues leyendo podrás aprender sobre: La clase ListView Crear un ...

informática desarrollo android

Este artículo te explicará el uso del Navigation Drawer en Android para crear una navegación a través de un Menú deslizante. Verás como implementar un Drawer Layout para el diseño. Aprenderás a manejar los eventos relacionados. Y también a complementar su funcionamiento con la action bar mediante un Action Bar Drawer Toggle. CONTENIDO ¿Cómo crear un menú deslizante con un Navigation Drawer? Ejem ...

informática desarrollo android

¿Te has preguntado como implementar pestañas en la Action Bar de tu aplicación Android, pero aún no encuentras el tutorial indicado?, si la respuesta es afirmativa, entonces te aseguro que este artículo te será de gran ayuda. Quédate y podrás aclarar el uso de Tabs y la navegación horizontal en tus aplicaciones Android. Además terminarás creando una aplicación con el siguiente aspecto: (Link de de ...

informática json desarrollo android

¿Quieres saber cómo leer datos JSON alojados en un servidor desde tu aplicación Android? ¿Te gustaría aprender formas rápidas y comprensibles para convertir objetos JSON en objetos Java? ¿Además de todo quieres ubicar tus datos en un ListView?...Si te quedas y sigues leyendo hasta el final, tus preguntas serán respondidas a través de varios ejemplos prácticos. CONTENIDO ¿Qué es JSON? ...

informática desarrollo android

Volley es una librería desarrollada por Google para optimizar el envío de peticiones Http desde las aplicaciones Android hacia servidores externos. Este componente actúa como una interfaz de alto nivel, liberando al programador de la administración de hilos y procesos tediosos de parsing, para permitir publicar fácilmente resultados en el hilo principal. En este artículo veremos la guía co ...

informática desarrollo android

Los Spinners son menús desplegables en Android que permiten al usuario decidirse por una camino entre varias opciones. De seguro alguna vez habrás visto un formulario en una aplicación donde te pidan elegir tu ciudad de una lista o cuando te permiten cambiar la temporalidad de los resultados proyectados desde un menú en la Action Bar. Ambos casos son ejemplos de Spinners y espero que este tutoria ...

informática desarrollo android

Los Spinners son menús desplegables en Android que permiten al usuario decidirse por una camino entre varias opciones. De seguro alguna vez habrás visto un formulario en una aplicación donde te pidan elegir tu ciudad de una lista o cuando te permiten cambiar la temporalidad de los resultados proyectados desde un menú en la Action Bar. Ambos casos son ejemplos de Spinners y espero que este tutoria ...