domingo, 15 de diciembre de 2013

Volley libreria de Google para hacer mas faciles y rapidas nuestras aplicaciones Android que descargan contenido en red.

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, peticiones o envio de datos entre cliente y servidor.

Para una mejor percepcion dejo el enlace a la explicacion oficial de los ingenieros de Google:
http://www.youtube.com/watch?v=yhv8l9F44qo

Aqui una traduccion de Google translate sobre las ventajas de Volley al aplicarla en nuestros proyectos:

-Volley automáticamente programa todas las solicitudes de red. Significa que Volley se hace cargo de toda ls 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 solicitud de cancelación. Esto significa que usted 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.

COMO UTILIZAR VOLLEY:
PASO 1: Clonar el proyecto de Github
Direccion: https://android.googlesource.com/platform/frameworks/volley.

Si no sabes como clonar un proyecto de Github te dejo el enlace hacia un tutorial.
 http://www.technotalkative.com/android-import-android-projects-from-git/

Si no quieres clonarla puedes descargarla de aqui:

 https://mega.co.nz/#!Rpd1TZBJ!NsGKxVL3klmXUl-9qX2SVkxI54do1P_-ub3vjqG9kLk


PROYECTO EJEMPLO:

Lo primero, dentro de Volley se encuentran dos clases java importantes:
1. Request queue: Si tu interés es utilizar 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 unica).
2. Request: 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, escuchadores(listeners), escuchador de errores(error listeners).

DESARROLLO:
A-) Importar Volley en nuestro espacio de trabajo de Eclipse.



Creamos un nuevo proyecto del tipo aplicacion Android:

Recuerda que en el paso anterior le das el nombre a tu proyecto el nombre de paquete(Package Name) con el cual sera reconocido en Google Play(Yo recomiendo utilizar "com.nombretuproyecto.nombretuproyectoapp" pero puedes llamarlo como quieras) luego los SDK minimos Target, compilacion y el Tema de tu App.

En mi caso le puse de nombre "EjemploVolley" al proyecto y al paquete "com.ejemplo.volley" como puedes ver a continuacion:
Importamos Volley haciendo clic derecho sobre la carpeta de proyecto luego "propiedades/android/"

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

En nuestro proyecto veremos como Volley trabaja en la peticion de imagenes para ello comenzaremos creando una clase java la cual nos servira para el tratamiento de la cache.



Luego crearemos una clase llamada ConvertidorJSON que nos servira para hacer peticiones 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 tu activity en este ejemplo cargaremos dos imagenes una por medio de URL y la otra a travez 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 imagenes inclusive en una conexion a internet no muy rapida, yo utilizo Genymotion como emulador es un poco mas rapido 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 travez del LogCat.

Esto ha sido todo en el post, espero haber aportado un poco al conocimiento general, saludos.

(Disculpen si en la ortografia faltaron acentos XD y tambien si el formato no es tan adecuado) cualquier duda pueden dejar su comentario

Recuerda que este blog sobrevive gracias a tus donaciones o clics en los anuncios, ya sabes como apoyar este recurso para continuar subiendo mas tutoriales. Gracias.