ASánchezDíaz

Autoaprendiendo .NET y otras cosas


Comunicación entre Activities con Intents y JSON

En la entrada anterior vimos cómo podemos pasar una cadena de texto a otra Activity, y el modo en que la segunda Activity la recupera para mostrarla.

Pero ¿y si lo que queremos pasar es un objeto personalizado? Por ejemplo, supongamos que tenemos una clase Usuario con las propiedades nombre y edad, de hecho, en nuestro proyecto anterior “ComunicacionJson” vamos a crear la clase Usuario:

package com.asanchezdiaz.comunicacionjson;

public class Usuario {

    private String nombre;
    private int edad;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }
}

Podemos crear una nueva clase haciendo click con el botón secundario del mouse en el paquete dónde queremos crear la clase y luego seleccionamos “New -> Java Class”, nos pedirá el nombre de la clase que será “Usuario”

Nueva clase

Android Studio crea y abre la clase en el editor. Reemplazamos el código por el que he puesto más arriba (respetando siempre el nombre de los paquetes, que en mi caso, comienzan por com.asanchezdiaz)

¿Cómo podemos pasar ahora un objeto derivado de esta clase a la otra Activity? Bueno, ya que el objeto tiene sólo dos propiedades, podemos pasarlas como explicábamos en la entrada anterior, almacenando en el Intent las dos propiedades y luego recuperándolas en la segunda Activity. Ya en la segunda Activity, creamos un nuevo objeto Usuario y asociamos el valor que hemos recuperado de cada propiedad al nuevo objeto.

Algo así:

En MainActivity.java

    public void mostrarUsuario(View view) {
        //Buscamos el control EditText por su id en el layout activity_main.xml
        EditText txtNombre = (EditText)findViewById(R.id.txtNombre);

        //Creamos un nuevo objeto Usuario y le asignamos las propiedades nombre y edad
        Usuario usuario = new Usuario();
        usuario.setNombre("Antonio");
        usuario.setEdad(38);

        //Crearemos un Intent en el que almacenaremos el nombre y la edad del usuario
        //por separado y que usaremos para iniciar la nueva Activity

        //Asociamos las dos Activities
        Intent intent = new Intent(this, VerNombreActivity.class);

        //Almacenamos el nombre en el Intent
        intent.putExtra("nombre", usuario.getNombre());
        intent.putExtra("edad", usuario.getEdad());

        //Iniciamos la Activity usando el Intent, que ya lleva el nombre
        startActivity(intent);
    }

Nota: si queremos que este método se ejecute al pulsar el botón en la interfaz, debemos modificar activity_main.xml para que el evento onclick del botón ejecute ahora este método:

    <Button
        android:text="Mostrar"
        android:onClick="mostrarUsuario"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Luego en VerNombreActivity.java

    private void mostrarNombreUsuario() {
        //Obtener el Intent que hemos recibido
        Intent intent = getIntent();

        //Obtener el nombre
        String nombre = intent.getStringExtra("nombre");

        //Ahora la edad: el valor 0 es el que se obtendrá por defecto
        // si no se encuentra el valor original
        int edad = intent.getIntExtra("edad", 0);

        //Creamos un nuevo Usuario y le asignamos el valor a sus propiedades
        Usuario usuario = new Usuario();
        usuario.setNombre(nombre);
        usuario.setEdad(edad);

        //Recuperar el TextView por su id
        TextView lblNombre = (TextView)findViewById(R.id.lblNombre);

        //Establecer el texto y mostrar nombre
        lblNombre.setText("Tu nombre es: " + usuario.getNombre() + " y tu edad es " + usuario.getEdad());

    }

Esto lógicamente debe funcionar… pero no es práctico si el objeto que queremos pasar es más complejo. Para esto, no apoyaremos en JSON y usaremos una librería para convertir objetos a JSON y viceversa: GSON. Esta técnica se denomina Serialización.

JSON

Tal y cómo se indica en la página de JSON, se trata de un formato de intercambio de información (objetos, datos…). Es independiente del lenguaje de programación que estemos usando (JAVA, C#, etc…). Un objeto en JSON estará acotado entre llaves “{” y “}”, dónde las propiedades del objeto estarán representas mediante pares “clave-valor” separados por comas. Si éstas propiedades son otros objetos, aparecerán anidados dentro del objeto principal. Si se trata de arrays, los valores estarán delimitados por corchetes “[” y “]”.

Por ejemplo, para el objeto Usuario que hemos creado en MainActivity.java el resultado al convertirlo en JSON es:


"usuario": 
{
  "nombre": "Antonio",
  "edad": 38
}

GSON

GSON es una librería de Google que nos permite realizar estas conversiones, en un sentido y en otro para JAVA. En el momento de escribir esta entrada, la última versión publicada es la 2.7.

Podemos descargar la librería desde http://repo1.maven.org/maven2/com/google/code/gson/gson/2.7/gson-2.7.jar

El siguiente paso será incorporar la librería al proyecto. Para ello, cambiaremos la vista de la pestaña 1:Project a “Project”, ahora localizamos la carpeta “libs”, como aparece resaltada en la imagen:

Carpeta libs

En esta carpeta se guardan las librerías, como GSON, que vamos a necesitar. Copiamos la librería gson-2.7.jar que hemos descargado a la carpeta libs.

Ahora debemos decirle a Android Studio que use la librería como dependencia. Para ello, editamos el archivo build.gradle que encontraremos en el directorio app del proyecto y añadiremos en la sección dependencies la línea:

compile files(‘libs/gson-2.7.jar’)

Dependencias Gradle

Una última cosa… cada vez que modifiquemos el archivo build.gradle es necesario sincronizar el proyecto pulsando el botón “Sync” como se ve en la imagen.

Sincronización

Tras esto, ya podemos usar la librería.

Modificaremos el método mostrarUsuario(View view) en MainActivity.java:

    public void mostrarUsuario(View view) {
        //Buscamos el control EditText por su id en el layout activity_main.xml
        EditText txtNombre = (EditText)findViewById(R.id.txtNombre);

        //Creamos un nuevo objeto Usuario y le asignamos las propiedades nombre y edad
        Usuario usuario = new Usuario();
        usuario.setNombre("Antonio");
        usuario.setEdad(38);
        
        //Creamos un objeto Gson
        Gson gson = new Gson();
        
        //Convertimos el objeto usuario a json
        String json = gson.toJson(usuario);

        //Crearemos un Intent y ahora pasaremos la cadena json
        //Asociamos las dos Activities
        Intent intent = new Intent(this, VerNombreActivity.class);

        //Almacenamos la cadena json en el Intent con el nombre que queramos
        intent.putExtra("json", json);

        //Iniciamos la Activity usando el Intent, que ya lleva el nombre
        startActivity(intent);
    }

Ahora de lugar de pasar las propiedades por separado, pasamos el objeto usuario “entero” sólo que “convertido en json”. La línea:

String json = gson.toJson(usuario);

es la encargada de convertir el objeto en json.

Hemos almacenado la cadena json en el intent con el nombre “json”, aunque podríamos haber usado cualquier otro nombre.

Ahora llega el momento de hacer la operación inversa.

En VerNombreActivity.java, modificaremos ahora el método mostrarNombreUsuario(), que quedará de la siguiente forma:

    private void mostrarNombreUsuario() {
        //Obtener el Intent que hemos recibido
        Intent intent = getIntent();

        //Recuperamos la cadena json
        String json = intent.getStringExtra("json");

        //Creamos un objeto Gson
        Gson gson = new Gson();
        
        //Creamos un nuevo Usuario a partir de json
        Usuario usuario = gson.fromJson(json, Usuario.class);

        //Recuperar el TextView por su id
        TextView lblNombre = (TextView)findViewById(R.id.lblNombre);

        //Establecer el texto y mostrar nombre
        lblNombre.setText("Tu nombre es: " + usuario.getNombre() + " y tu edad es " + usuario.getEdad());

    }

La línea

Usuario usuario = gson.fromJson(json, Usuario.class);

es la que hace la conversión. Ahora, Gson usa el método fromJson(json, Usuario.class), que sólo necesita conocer la información (json) y el tipo de objeto o clase para saber en qué convertir la cadena (Usuario.class).

El código completo de Usuario.cs, MainActivity.java y VerNombreActivity.java

MainActivity.java

package com.asanchezdiaz.comunicacionjson;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import com.google.gson.Gson;

public class MainActivity extends AppCompatActivity {

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

    public void mostrarNombre(View view) {
        //Buscamos el control EditText por su id en el layout activity_main.xml
        EditText txtNombre = (EditText)findViewById(R.id.txtNombre);

        //Leemos el nombre del usuario y lo guadamos
        String nombre = txtNombre.getText().toString();

        //Crearemos un Intent en el que almacenaremos el nombre del usuario
        //y que usaremos para iniciar la nueva Activity

        //Asociamos las dos Activities
        Intent intent = new Intent(this, VerNombreActivity.class);

        //Almacenamos el nombre en el Intent
        intent.putExtra("nombre", nombre);

        //Iniciamos la Activity usando el Intent, que ya lleva el nombre
        startActivity(intent);
    }

    public void mostrarUsuario(View view) {
        //Buscamos el control EditText por su id en el layout activity_main.xml
        EditText txtNombre = (EditText)findViewById(R.id.txtNombre);

        //Creamos un nuevo objeto Usuario y le asignamos las propiedades nombre y edad
        Usuario usuario = new Usuario();
        usuario.setNombre("Antonio");
        usuario.setEdad(38);

        //Creamos un objeto Gson
        Gson gson = new Gson();

        //Convertimos el objeto usuario a json
        String json = gson.toJson(usuario);

        //Crearemos un Intent y ahora pasaremos la cadena json
        //Asociamos las dos Activities
        Intent intent = new Intent(this, VerNombreActivity.class);

        //Almacenamos la cadena json en el Intent con el nombre que queramos
        intent.putExtra("json", json);

        //Iniciamos la Activity usando el Intent, que ya lleva el nombre
        startActivity(intent);
    }
}

VerNombreActitivy.java

package com.asanchezdiaz.comunicacionjson;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.google.gson.Gson;

public class VerNombreActivity extends AppCompatActivity {

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

    private void mostrarNombreUsuario() {
        //Obtener el Intent que hemos recibido
        Intent intent = getIntent();

        //Recuperamos la cadena json
        String json = intent.getStringExtra("json");

        //Creamos un objeto Gson
        Gson gson = new Gson();

        //Creamos un nuevo Usuario a partir de json
        Usuario usuario = gson.fromJson(json, Usuario.class);

        //Recuperar el TextView por su id
        TextView lblNombre = (TextView)findViewById(R.id.lblNombre);

        //Establecer el texto y mostrar nombre
        lblNombre.setText("Tu nombre es: " + usuario.getNombre() + " y tu edad es " + usuario.getEdad());

    }
}

Usuario.cs

package com.asanchezdiaz.comunicacionjson;

public class Usuario {

    private String nombre;
    private int edad;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }
}

Espero que le sirva a alguien.

Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *