sábado, 1 de marzo de 2014

Framework Volley - Android


Quiero arrancar marzo con TODO! porque es uno de los meses en donde hacemos las planificaciones de nuestras capacitaciones, proyectos, y también en donde nos embarcamos en nuevos aprendizajes. En esta secuencias de post que hoy comienzan, vamos a repasar un par de frameworks y utilidades, dentro del ecosistema Android.

Ya sabemos programar en Android, ya hemos realizado varias aplicaciones, y nos fuimos dando cuenta de que varias veces copiamos y pegamos el mismo codigo de ciertas actividades y clases de utilidades, para realizar tareas que son muy, pero muy parecidas.
Ese es el caso de las Tareas Asyncronicas para comunicarse con un servidor mediante HTTP.
Entonces....algo debe existir, algún framework debe ya existir para evitar repetir ese "copy-paste" de nuestro codigo.

Bueno.... si, existe, y se llama "Framework Volley", y tambien es de la gente de Google. A continuación, repasamos un Kick-Off del framework, y las principales caracteristicas.

¿Que es Volley?

Es una libreria que podremos integrar a nuestro proyecto Android para hacer mas faciles y rapidas las operaciones de red como: Descarga de imagenes, pedidos de datos entre cliente y servidor.

Para una mejor explicacion, tenemos el video oficial de los ingenieros de Google:
http://www.youtube.com/watch?v=yhv8l9F44qo

¿Ventajas de Volley? 


Volley automáticamente programa todas las solicitudes de red. Significa que Volley se hace cargo de toda las solicitudes de red que su aplicación ejecuta para ir a buscar la respuesta o la imagen de la web.
-Volley ofrece disco transparente y el almacenamiento en caché de memoria.
-Volley ofrece una potente API de solicitud de cancelación. Esto significa que se puede cancelar la solicitud o puede establecer bloques o ámbitos de peticiones para cancelar.
-Volley proporciona potentes capacidades de personalización.
-Volley proporciona herramientas de depuración y rastreo. Si, està bueno debugear una libreria.

Kick-Off de Volley


Primero, vamos a clonar el proyecto de Github
Direccion: https://android.googlesource.com/platform/frameworks/volley.

Si no sabes como clonar un proyecto de Github, ya mismo ponete a googlear por un tutorial.
 
Si no quieres clonarla puedes descargarla de este link: 
 https://mega.co.nz/#!Rpd1TZBJ!NsGKxVL3klmXUl-9qX2SVkxI54do1P_-ub3vjqG9kLk


Lo primero, es que dentro de Volley se encuentran dos clases java importantes:
1. Request queue: Es para utilizar a Volley para el envío de solicitudes a la red, puedes hacer una cola de peticiones en demanda si lo deseas, pero por lo general, la libreria las crea desde el principio, en el momento de arranque, y mantenerlo alrededor y utilizarlo como Singleton (instancia única).
2Request: Contiene todos los detalles necesarios para hacer llamadas de API Web. Por ejemplo: el método a utilizar (GET o POST), datos de la solicitud, listeners (comunes y de errores)

Ahora, vamos al Eclipse, y nos vamos a Importar Volley en nuestro espacio de trabajo de Eclipse.





Creamos un nuevo proyecto del tipo aplicación Android (todo esto ya lo recontra saben)



En la siguiente imagen pueden ver, como el nombre del proyecto es "EjemploVolley"  y al paquete "com.ejemplo.volley" como puedes ver a continuación:

Importamos Volley haciendo clic derecho sobre la carpeta de proyecto luego "propiedades/android/"

Recuerda agregar al Manifest de tu aplicación los permisos de Internet:
<uses-permission android:name="android.permission.INTERNET"/>


En nuestro proyecto veremos como Volley trabaja en el pedido de imagenes, y para ello comenzaremos creando una clase java la cual nos servirá para el tratamiento de la cache.



Luego crearemos una clase llamada ConvertidorJSON que nos servirá para hacer pedidos de url de imagenes via JSON.

package com.ejemplo.volley;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class ConvertidorJSON {
static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";
   public ConvertidorJSON()  {
  
   }
   public JSONObject getJSONFromUrl(String url) {    
        try {          
           DefaultHttpClient httpClient = new DefaultHttpClient();
           HttpPost httpPost = new HttpPost(url);

           HttpResponse httpResponse = httpClient.execute(httpPost);
           HttpEntity httpEntity = httpResponse.getEntity();
           is = httpEntity.getContent();           

       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       } catch (ClientProtocolException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }
        
       try {
           BufferedReader reader = new BufferedReader(new InputStreamReader(
                   is, "UTF-8"), 8);
           StringBuilder sb = new StringBuilder();
           String line = null;
           while ((line = reader.readLine()) != null) {
               sb.append(line + "\n");
           }
           is.close();
           json = sb.toString();
       } catch (Exception e) {
           Log.e("Buffer Error", "Error converting result " + e.toString());
       }

       // try parse the string to a JSON object
       try {
           jObj = new JSONObject(json);
       } catch (JSONException e) {
           Log.e("JSON Parser", "Error parsing data " + e.toString());
       }

       // return JSON String
       return jObj;

   }
}


Luego creamos el codigo de nuestra vista XML. En el cual tendremos ademas de un control ImageView tradicional uno referente a la libreria Volley que es el NetworkImageView.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="150dp"
        android:layout_height="170dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/ic_launcher" />

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/networkImageView"
        android:layout_width="150dp"
        android:layout_height="170dp"
        android:layout_below="@+id/imageView1"
        android:layout_centerHorizontal="true"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical" >

      
    </LinearLayout>

</RelativeLayout>

El codigo anterior deberia generarnos la siguiente vista grafica.



La siguiente codificacion corresponde al codigo de la activity en este ejemplo cargaremos dos imagenes una por medio de URL y la otra a traves de la lectura de un JSON generado por un Servicio Web en PHP.

package com.ejemplo.volley;

import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;
import com.technotalkative.volleyimageloading.R;

public class MainActivity extends Activity {

private RequestQueue mRequestQueue;
private ImageLoader imageLoader;
private String img1, img2;
private ImageView imageView;
private NetworkImageView networkImageView;
String urlimg1, urlimg2;
private static final String IMAGE_URL = "http://developer.android.com/images/gp-device.png";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

networkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
imageView = (ImageView) findViewById(R.id.imageView1);
new MiTarea().execute("http://miweb/ws/webservice.php");
mRequestQueue = Volley.newRequestQueue(this);
imageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(
BitmapLruCache.getDefaultLruCacheSize()));

}

 

private class MiTarea extends AsyncTask<String, Float, Integer> {
private static final String im1= "nombreimg1";
private static final String im2= "nombreimg2";

protected void onPreExecute() {
// antes de comenzar
}

protected Integer doInBackground(String... params) {

String url = params[0];
try {

try {
ConvertidorJSON jp = new ConvertidorJSON();
JSONObject json = jp.getJSONFromUrl(url);
img1 = json.getJSONArray(im1).getString(0);
img2 = json.getJSONArray(im2).getString(0);

} catch (JSONException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
String urlbase = "http://miweb/ubicaciondeimagenes/";

// urls para imagenes
urlimg1 = urlbase + "directorio/" + img1;// url para imagen 1
urlimg2 = urlbase + "directorio/" + img2; // url para imagen2

return null;

}

protected void onProgressUpdate(Float... valores) {

}

protected void onPostExecute(Integer bytes) {
networkImageView.setImageUrl(urlimg1, imageLoader);
imageLoader.get(urlimg1, ImageLoader.getImageListener(imageView,
R.drawable.ic_launcher, R.drawable.ic_error));
}
}

}


Podras observar que para la descarga de imagenes se hizo en un hilo secundario gracias a la potencia de la clase abstracta Asyntask http://developer.android.com/reference/android/os/AsyncTask.html
de Android, toda accion de descarga de contenido en red es preferible hacerlo en segundo plano a traves de un nuevo hilo de ejecucion.

A continuacion podemos ver la ejecucion de nuestro proyecto y la rapidez con la cual descarga las imágenes inclusive en una conexion a internet no muy rapida, yo uso Genymotion como emulador es un poco mas rápido que los emuladores del SDK de Android. http://www.genymotion.com/

Puedes por ejemplo programar un boton y mediante el descargar las imagenes para que veas como Volley realiza su trabajo a traves del LogCat.

Hasta acà, con la introduccion y resumen de lo que es el Framework Volley, màs adelante sin duda que vamos a ir agregando algun que otro ejemplo màs de este prometedor framework.

No hay comentarios:

Publicar un comentario