Mostrando postagens com marcador Parcelable. Mostrar todas as postagens
Mostrando postagens com marcador Parcelable. Mostrar todas as postagens

segunda-feira, 11 de janeiro de 2010

Android: Passando objetos em Intents

Olá povo,

Algumas pessoas me perguntaram como passar objetos entre telas no Android ao invés de passar apenas primitivos. Um exemplo típico é uma tela que lista algum tipo de informação e quando algum item dessa lista é selecionado, o objeto da classe referente aquela informação deveria ser passado para uma tela de detalhes do mesmo.

Para resolver isso, eu passava para a tela de detalhamento apenas um identificador do objeto (um código, por exemplo) e lá eu fazia uma consulta ao controlador que me retornava o objeto desejado.

Essa é uma abordagem boa, e até aconselho. Mas quem quiser mesmo passar obejtos entre telas podemos utilizar a interface android.os.Parcelable. A classe que implementar essa interface pode ser adicionada a uma Intent.

Vamos fazer um pequeno exemplo aqui criando uma classe Cliente com dois atributos (código e nome) e ela implementará a interface Parcelable.
import android.os.Parcel;
import android.os.Parcelable;

public class Cliente implements Parcelable {
 private int codigo;
 private String nome;

 public Cliente(int codigo, String nome) {
   this.codigo = codigo;
   this.nome = nome;
 }

 private Cliente(Parcel p){
   codigo = from.readInt();
   nome = from.readString();
 }

 public static final Parcelable.Creator<Cliente>
   CREATOR = new Parcelable.Creator<Cliente>() {

   public Cliente createFromParcel(Parcel in) {
     return new Cliente(in);
   }

   public Cliente[] newArray(int size) {
     return new Cliente[size];
   }
 };

 public int getCodigo() {
   return codigo;
 }

 public void setCodigo(int codigo) {
   this.codigo = codigo;
 }

 public String getNome() {
   return nome;
 }

 public void setNome(String nome) {
   this.nome = nome;
 }

 @Override
 public int describeContents() {
   return 0;
 }

 @Override
 public void writeToParcel(Parcel dest, int flags) {
   dest.writeInt(codigo);
   dest.writeString(nome); 
 }
}
Vejam que a classe Cliente implementa a interface Parcelable que tem dois métodos que devem ser implementados: writeToParcel e describeContents. O primeiro método serve para serializar as informações da classe, já o segundo é um inteiro qualquer que identifica a classe :)

A segunda coisa importante a destacar é o atributo estático CREATOR que é do tipo Parcelable.Creator. Segundo a própria documentação, todas as classes que desejem implementar Parcelable devem ter essa variável. É ela que cria os objetos a partir de um Parcel, classe que a grosso modo, junta as funcionalidades de um DataInputStream e DataOutputStream para serializar e deserializar objetos. Veja que ela chama o construtor privado de Cliente que recebe um Parcel que nos permite ler dados dele e passando para os atributos.
Agora vamos ver como passar nosso objeto via Intent:
Cliente cliente = new Cliente(1, "Glauber");

Intent it = new Intent(this, Teste2Activity.class);
   
it.putExtra("cliente", cliente);
   
startActivity(it);
E para ler o conteúdo é tão simples quando enviar:
Cliente c = 
  getIntent().getExtras().getParcelable("cliente");

EDITADO em 08/08/2012:
Achei uma maneira muuuito mais simples (porém mais lenta em tempo de execução) de fazer a passagem de objetos entre Activities. Basta fazer com que eles implementem a interface java.io.Serializable.
public class Pessoa implements Serializable {
  // Seus atributos, gets e sets ...
}
Dessa forma você pode passar os objetos da classe Pessoa para outras activities via Intent normalmente, inclusive adicionando-os a listas (a classe ArrayList é serializada).
 
ArrayList<Pessoa> pessoas = new ArrayList<Pessoa>();
pessoas.add(new Pessoa(1, "Glauber"));
pessoas.add(new Pessoa(2, "Nelson"));
        
Intent it = new Intent(this, Tela2Activity.class);
// passando a lista
it.putExtra("pessoas", pessoas); 
// passando um objeto
it.putExtra("pessoa", pessoas.get(0)); 
startActivity(it);


E pra recuperar:
Pessoa pessoa = 
  (Pessoa) getIntent().getSerializableExtra("pessoa");

ArrayList<Pessoa> pessoas = (ArrayList<Pessoa>) 
  getIntent().getSerializableExtra("pessoas");
  
System.out.println("Pessoa: "+ pessoa.getNome());
System.out.println(
  "Pessoas: "+ pessoas.get(0).getNome());

4br4ç05,
nglauber