Como enviar um objeto de uma Atividade Android para outro usando Intents?


849

Como posso passar um objeto de um tipo personalizado de uma atividade para outra usando o putExtra()método da classe Intent ?


@UMMA - você não precisa continuar marcando suas perguntas como "Wiki da Comunidade". Dê uma olhada aqui: meta.stackexchange.com/questions/11740/…
Dave Webb

1
@Paresh: o link que você forneceu está quebrado. você poderia fornecer uma alternativa?
Antiplex



eu encontrei um simples e elegante método stackoverflow.com/a/37774966/6456129
Yessy

Respostas:


751

Se você está apenas passando objetos, o Parcelable foi projetado para isso. Requer um pouco mais de esforço do que usar a serialização nativa de Java, mas é muito mais rápido (e quero dizer, MUITO MAIS rápido).

Nos documentos, um exemplo simples de como implementar é:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

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

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Observe que, no caso de você ter mais de um campo para recuperar de um determinado pacote, você deve fazer isso na mesma ordem em que os colocou (ou seja, em uma abordagem FIFO).

Depois de ter seus objetos implementar Parcelableé apenas uma questão de colocá-los em suas Intenções com putExtra () :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Em seguida, você pode recuperá- los com getParcelableExtra () :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Se sua classe de objeto implementa Parcelable e Serializable, certifique-se de converter para um dos seguintes:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
Como isso seria implementado onde mData é um objeto (por exemplo, JSONObject) e não um int?
Peter Ajtai #

301
Por que não pode simplesmente passar o objeto sem tudo isso? Queremos passar um objeto que já está na memória.
ceklock

110
@tecnotron seus aplicativos beacuse estão em processos diferentes e têm espaços de endereço de memória separados, você não pode simplesmente enviar ponteiro (referência) para o bloco de memória em seu processo e esperar que ele esteja disponível em outro processo.
marcinj

12
O que faço se não puder tornar a classe do objeto serializável ou Parceable?
Amel Jose

11
@ceklock A razão por trás disso é a seguinte: Quando a atividade é atrasada e posteriormente eliminada da memória, e quando o usuário a abre no menu recente, ela deve criar a Atividade de onde parou. Tem que ser a mesma interface do usuário. O objeto não está na memória neste caso. Mas a intenção é.
Tasomaniac

194

Você precisará serializar seu objeto em algum tipo de representação de string. Uma possível representação de cadeia de caracteres é JSON, e uma das maneiras mais fáceis de serializar de / para JSON no Android, se você me perguntar, é pelo Google GSON .

Nesse caso, basta colocar o valor de retorno da string (new Gson()).toJson(myObject);e recuperar o valor da string e usá fromJson-lo para transformá-lo novamente em seu objeto.

Se seu objeto não for muito complexo, no entanto, pode não valer a pena a sobrecarga, e você pode considerar a possibilidade de passar os valores separados do objeto.


19
Estou supondo que a resposta do fiXedd resolve o mesmo problema sem o uso de bibliotecas externas, de uma maneira que é simplesmente tão preferível, que ninguém jamais deve ter um motivo para seguir a solução que eu forneci (sem perceber, na época, solução brilhante do fiXedd)
David Hedlund

5
Eu acho que está correto. Além disso, o JSON é um protocolo mais apropriado para o cliente / servidor e não thread a thread.
mobibob

16
Não é necessariamente uma má ideia, esp. já que o Gson é muito mais simples de usar do que implementar parcelable para todos os objetos que você deseja enviar.
usar o seguinte código

7
como iam usando gson no meu aplicativo, essa é uma maneira muito fácil e agradável!
Lars

16
Resposta agradável, embora solução completa seria String s = (new Gson().toJson(client));e depoisCli client = new Gson().fromJson(s, Cli.class);
Joaquin Iurchuk

155

Você pode enviar um objeto serializável através da intenção

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
você também pode enviar objetos Parcelable com intenção.
gil tony

6
"Serializable é comicamente lento no Android. Fronteira inútil em muitos casos, de fato." olhada stackoverflow.com/questions/5550670/...
de Seraphim

e se a atividade já estiver em execução, é necessário fazer startActivity (i); ? Quero dizer, posso fazer a atividade A chamar a atividade B e isso retorna os dados à atividade A ? estou confuso?
Francisco Corrales Morales

3
O desempenho do @ Seraphim é importante se você estiver serializando muitos objetos, mas o usuário não notará se a serialização de um objeto leva 1 ms ou 10 ms. Se uma intenção extra já é, Serializablemas não Parcelableé, raramente vale a pena fazer isso Parcelable.
Kevin Krumwiede 01/07

67

Para situações em que você sabe que passará dados dentro de um aplicativo, use "globais" (como Classes estáticas)

Aqui está o que Dianne Hackborn (hackbod - uma engenheira de software do Google Android) disse sobre o assunto:

Para situações em que você sabe que as atividades estão em execução no mesmo processo, basta compartilhar dados por meio de globais. Por exemplo, você pode ter um global HashMap<String, WeakReference<MyInterpreterState>> e, ao criar um novo MyInterpreterState, criar um nome exclusivo para ele e colocá-lo no mapa de hash; para enviar esse estado para outra atividade, basta colocar o nome exclusivo no mapa de hash e, quando a segunda atividade for iniciada, ele poderá recuperar MyInterpreterState do mapa de hash com o nome que recebe.


25
sim, achei estranho que recebêssemos essas intenções de uso e, em seguida, um engenheiro de ponta nos diz para usar apenas globais para nossos dados. Mas é direto da boca dos cavalos.
Richard Le Mesurier 22/02

1
A fraca referência aqui não seria vítima da coleta de lixo?
uLYsseus

1
@uLYsseus acho que essa é a idéia, uma vez que você está feito com eles nas atividades ... por isso, quando as actividades relevantes são destruídos, ele vai permitir que ele gc
Peter Ajtai

1
@RichardLeMesurier Eu estava pensando a mesma coisa, mas depois olhei para a postagem acima mencionada dos Grupos do Google de Dianne Hackborn, e ela menciona que realmente o único problema com os globais seria ao usar intenções implícitas (que podem iniciar uma atividade fora do seu pacote ) Isso faz sentido, como Dianne menciona, porque essas atividades provavelmente teriam zero conhecimento dos tipos personalizados que você está passando para eles. Uma vez eu li isso, ele tornou claro para mim por que globals pode não ser uma má rota tal, dadas as circunstâncias, e eu percebi que eu iria compartilhar no caso de outros estavam curiosos demais
BMB

as intenções foram superengenhadas a um ponto em que a intenção poderia ser transmitida para um computador diferente. o que obviamente não é uma boa maneira de fazer qualquer coisa quando você realmente tem apenas um processo em que está se metendo. razões pelas quais não é bom: uso de memória, uso de CPU, uso de bateria. o último fez especialmente as escolhas de design com intenções bastante desconcertantes em retrospectiva. há pessoas que insistem que são uma boa ideia, geralmente porque "o Google disse isso".
Lassi Kinnunen

49

Sua classe deve implementar Serializable ou Parcelable.

public class MY_CLASS implements Serializable

Uma vez feito, você pode enviar um objeto em putExtra

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

Para obter extras, você só precisa fazer

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

Se sua turma implementa o Parcelable use next

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

Espero que ajude: D


6
Sua classe deve implementar Serializableestá errada. A classe pode implementar, Parcelablepor exemplo.
Marc Plano-Lesay

Qual é a diferença entre Parcelable e Serializable @Kernald? em termos de tempo de processamento, é mais lento / não é a melhor prática ou algo assim?
Gmuruh 17/07/2014

Embora Serializableseja uma interface Java padrão, Parcelableé específica para Android. Em termos de desempenho, Parcelable é mais eficiente: developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay

35

Resposta curta para necessidade rápida

1. Implemente sua classe para serializável.

Se você tem alguma classe interna, não se esqueça de implementá-la também em serializável !!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. Coloque seu objeto em intenção

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. E receba seu objeto na outra classe de atividade

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");


Você pode conseguir a mesma coisa implementando a interface Parcelable. A interface Parcelable leva mais tempo para ser implementada em comparação com Serializable devido ao tamanho do código. Mas seu desempenho é mais rápido que o serializável e usa menos recursos.
Kwnstantinos Nikoloutsos

27

se sua classe de objeto é implementada Serializable, você não precisa fazer mais nada, pode transmitir um objeto serializável.
é isso que eu uso.


24

implementar serializável em sua classe

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

        public void setName(String name) {
           this.name = name;
        }
}

Então você pode passar este objeto na intenção

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

int a segunda atividade, você pode obter dados como este

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

Mas quando os dados se tornarem grandes, esse método será lento.


16

Você pode usar o pacote Android para fazer isso.

Crie um pacote da sua classe como:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

Em seguida, passe este pacote com INTENT. Agora você pode recriar seu objeto de classe passando o pacote como

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

Declare isso em sua classe Personalizada e use.


1
Preferível para direcionar a implementação de Parcelable, IMHO. O pacote implementa o Parcelable por si só, para que você ainda tenha o ganho de desempenho, evitando todos os problemas ao implementá-lo. Em vez disso, você pode usar pares de valores-chave para armazenar e recuperar os dados que são mais robustos de longe do que depender de um mero pedido.
Risadinha

Parcelable parece complicado para mim, na minha resposta acima, estou usando o método toBundle da classe em seu objeto para que o objeto seja convertido em pacote e, em seguida, possamos usar o construtor para converter o pacote no objeto de classe.
Om252345 de

Esta solução só é viável se você estiver passando um único objeto através de uma intenção.
TheIT

Como json, mas json é leve, eu acho.
David

O objeto ao recuperá-lo será o mesmo objeto ou uma cópia?
Markus

16

Existem algumas maneiras pelas quais você pode acessar variáveis ​​ou objetos em outras classes ou atividades.

A. Banco de Dados

B. preferências compartilhadas.

C. Serialização de objetos.

D. Uma classe que pode conter dados comuns pode ser denominada Utilitários comuns, depende de você.

E. Passagem de dados através de Intents e Parcelable Interface.

Depende das necessidades do seu projeto.

A. Banco de Dados

SQLite é um banco de dados de código-fonte aberto que é incorporado ao Android. O SQLite suporta recursos padrão de banco de dados relacional, como sintaxe SQL, transações e instruções preparadas.

Tutoriais - http://www.vogella.com/articles/AndroidSQLite/article.html

B. Preferências compartilhadas

Suponha que você queira armazenar o nome de usuário. Portanto, agora haverá duas coisas: um Nome de Usuário Chave , Valor Valor.

Como guardar

 // Create an object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
 //now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();
 //put your value
 editor.putString("userName", "stackoverlow");

 //commits your edits
 editor.commit();

Usando putString (), putBoolean (), putInt (), putFloat (), putLong (), você pode salvar o tipo de dt desejado.

Como buscar

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. Serialização de objetos

A serialização de objetos é usada se queremos salvar um estado de objeto para enviá-lo pela rede ou você pode usá-lo também para sua finalidade.

Use java beans e armazene-o como um de seus campos e use getters e setter para isso

JavaBeans são classes Java que possuem propriedades. Pense nas propriedades como variáveis ​​de instância privada. Como eles são particulares, a única maneira de acessá-los de fora da classe é através dos métodos da classe. Os métodos que alteram o valor de uma propriedade são chamados métodos setter, e os métodos que recuperam o valor de uma propriedade são chamados métodos getter.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

Defina a variável no seu método de email usando

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

Em seguida, use Serialzation do objeto para serializar esse objeto e em sua outra classe desserialize esse objeto.

Na serialização, um objeto pode ser representado como uma sequência de bytes que inclui os dados do objeto, além de informações sobre o tipo do objeto e os tipos de dados armazenados no objeto.

Depois que um objeto serializado é gravado em um arquivo, ele pode ser lido e desserializado, ou seja, as informações de tipo e bytes que representam o objeto e seus dados podem ser usados ​​para recriar o objeto na memória.

Se você deseja um tutorial para isso, consulte este link

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

Obter variável em outras classes

D. Utilidades comuns

Você pode fazer uma aula por si mesmo, que pode conter dados comuns que você precisa com freqüência em seu projeto.

Amostra

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. Passando dados por meio de intenções

Por favor, consulte este tutorial para esta opção de transmissão de dados.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


Bom tutorial que você mencionou em (E) sobre a passagem de dados através do Intents.
Remrick

15

Obrigado pela ajuda parcelável, mas encontrei mais uma solução opcional

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

Na Atividade Um

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

Obter dados na atividade 2

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
boa resposta, mas aumentar a sua Coding Standards ... +1 embora para trazer Serializable na competição entanto Parcellables são muito mais rápido ...
Amit

13

Eu uso o Gson com sua API tão poderosa e simples para enviar objetos entre atividades,

Exemplo

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

2 funções que você as adiciona aos objetos que deseja enviar

Uso

Enviar objeto de A para B

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

Receber em B

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

Eu o uso quase em todos os projetos que faço e não tenho problemas de desempenho.


Obrigado, isso me salvou horas de supercomplicação.
Hristo Stoyanov

10

Eu lutei com o mesmo problema. Eu o resolvi usando uma classe estática, armazenando quaisquer dados que eu desejasse em um HashMap. No topo, uso uma extensão da classe Activity padrão, onde substituí os métodos onCreate an onDestroy para fazer o transporte e a limpeza de dados ocultos. Algumas configurações ridículas precisam ser alteradas, por exemplo, manipulação de orientação.

Anotação: Não fornecer objetos gerais a serem passados ​​para outra atividade é um problema. É como dar um tiro no joelho e esperar ganhar 100 metros. "Parcable" não é um substituto suficiente. Isso me faz rir ... Não quero implementar essa interface na minha API livre de tecnologia, pois menos quero introduzir uma nova Camada ... Como poderia ser, estarmos em programação móvel tão longe de nós? paradigma moderno ...


9

Na sua primeira atividade:

intent.putExtra("myTag", yourObject);

E no seu segundo:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

Não se esqueça de tornar seu objeto personalizado serializável:

public class myCustomObject implements Serializable {
...
}

Parcelable é melhor que Serializable! Evite usar o Serializable no seu código Android!
Filipe Brito

7

Outra maneira de fazer isso é usar o Applicationobjeto (android.app.Application). Você define isso em seu AndroidManifest.xmlarquivo como:

<application
    android:name=".MyApplication"
    ...

Você pode chamar isso de qualquer atividade e salvar o objeto na Applicationclasse.

Na FirstActivity:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

No SecondActivity, faça:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

Isso é útil se você tiver objetos com escopo no nível do aplicativo, ou seja, eles devem ser usados ​​em todo o aplicativo. O Parcelablemétodo ainda é melhor se você deseja controle explícito sobre o escopo do objeto ou se o escopo é limitado.

Isso evita o uso de todos Intents, no entanto. Não sei se eles combinam com você. Outra maneira que usei isso é fazer com que os intidentificadores de objetos sejam enviados através de intenções e recuperem objetos que eu tenho no Maps no Applicationobjeto.


1
Não é o caminho certo para fazer as coisas, pois os objetos podem ser variáveis. O seu pode funcionar se você falar sobre objetos estáticos ao longo do ciclo de vida do aplicativo, mas algumas vezes precisamos de objetos passivos que podem ser gerados usando o serviço da Web ou mais. Stackoverflow.com / a / 2736612/716865
Muhannad A.Alhariri

Eu usei com sucesso com objetos gerados a partir de serviços da web, tendo um escopo de aplicativo Maponde os objetos são armazenados e recuperados usando um identificador. O único problema real com essa abordagem é que o Android limpa a memória depois de um tempo, então você precisa verificar se há nulos no seu onResume (acho que os Objetos passados ​​por intenção são persistentes, mas não tenho certeza). Além disso, não vejo isso como sendo significativamente inferior.
Saad Farooq

Esta é a melhor resposta. Mostra como atividades diferentes podem fazer referência ao mesmo modelo de dados. Levei muito tempo para descobrir isso!
Markus

6

no seu modelo de classe (Object), implemente Serializable, por exemplo:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

e sua primeira atividade

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

e sua segunda atividade (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

boa sorte!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

Passando os dados:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

Recuperando os dados:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

a solução mais fácil que encontrei é .. criar uma classe com membros de dados estáticos com setters de getters.

definir a partir de uma atividade e obter de outra atividade esse objeto.

atividade A

mytestclass.staticfunctionSet("","",""..etc.);

atividade b

mytestclass obj= mytestclass.staticfunctionGet();

1
ou criar uma série serializável para passar para outra atividade, o que você deseja passar.
UMAR

9
Lembre-se de não colocar objetos grandes e gordos. A vida útil desse objeto será igual à vida útil do aplicativo. E nunca armazene visualizações. Este método também garante vazamentos de memória.
Reno

1
Essa resposta é útil, mas não uma melhor solução em termos de otimização de memória e de recursos
Atul Bhardwaj

1
Isso quebra os princípios de POO, introduzindo variáveis ​​globais. Você nunca sabe em que estado eles estão, se estão definidos ou não, são usados ​​por muitos encadeamentos e é necessário lidar com essa complexidade. Geralmente é um bom vazamento de memória, porque você nem sabe quando liberar essas variáveis. Para não dizer que introduz acoplamento direto rígido entre diferentes módulos do aplicativo.
afrish

2
WTF? As outras duas respostas são muito superiores.
IcyFlame 11/05

4

você pode usar os métodos putExtra (Serializable ..) e getSerializableExtra () para passar e recuperar objetos do seu tipo de classe; você terá que marcar sua classe como serializável e verifique se todas as suas variáveis ​​de membro também são serializáveis ​​...


4

Criar aplicativo Android

Arquivo >> Novo >> Aplicativo para Android

Digite o nome do projeto: android-pass-object-to-activity

Pakcage: com.hmkcode.android

Mantenha outras seleções padrão, vá em Avançar até chegar em Concluir

Antes de começar a criar o aplicativo, precisamos criar a classe POJO "Person", que usaremos para enviar objetos de uma atividade para outra. Observe que a classe está implementando a interface serializável.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

Dois layouts para duas atividades

activity_main.xml

<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout 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:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

Duas Classes de Atividade

1) ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

Usando a biblioteca Gson do google, você pode passar o objeto para outras atividades.

Considere uma classe de bean como esta

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Precisamos passar o objeto da classe Example

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

Para ler, precisamos fazer a operação reversa no NextActivity

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

Adicione esta dependência em gradle

compile 'com.google.code.gson:gson:2.6.2'

3
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);

3

Eu sei que isso é tarde, mas é muito simples. Tudo o que você precisa fazer é deixar sua classe implementar Serializable como

public class MyClass implements Serializable{

}

então você pode passar para uma intenção como

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

Para obtê-lo, você simplesmente chama

MyClass objec=(MyClass)intent.getExtra("theString");

2

Se você tiver uma classe singleton (fx Service) atuando como gateway para a camada do modelo, ela poderá ser resolvida com uma variável nessa classe com getters e setters para ela.

Na atividade 1:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

Na atividade 2:

private Service service;
private Order order;

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

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

Em serviço:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

Esta solução não requer nenhuma serialização ou outro "empacotamento" do objeto em questão. Mas isso só será benéfico se você estiver usando esse tipo de arquitetura.


Quais são as desvantagens dessa abordagem? Parece tão lógico e esbelto. Eu sempre leio que você não deveria fazer isso, mas nunca recebi uma boa explicação sobre o que poderia dar errado.
Markus

Como não consigo mais editar meu comentário: essa não é a única solução possível para obter uma referência a um objeto em vez de uma cópia? Preciso recuperar o mesmo objeto e não uma cópia!
Markus

Eu acho que isso é um pouco desencorajado por causa do alto acoplamento que leva a. Mas sim, até onde posso ver, essa abordagem é a mais viável se você precisar do objeto real. Como sempre na programação, você pode fazer o que quiser, apenas com cuidado. Essa solução funcionou para mim e eu a prefiro, pois uso essa arquitetura de qualquer maneira.
Kitalda

Na verdade, acabei estendendo a classe Application e armazenei meu modelo de dados lá. Nos Intents, retransmiti apenas o ID dos objetos de dados que poderiam ser usados ​​para recuperar o objeto original da classe Application. Além disso, a classe de aplicativo estendida notifica todos os objetos que usam o modelo de dados se ele mudar através de um conceito de ouvinte padrão. Eu sei que isso se encaixa apenas no meu caso, em que preciso compartilhar um modelo de dados em todo o aplicativo, mas nesse caso é perfeito e também não há classes e campos estáticos!
Markus

2

De longe, a maneira mais fácil do IMHO de empacotar objetos. Você acabou de adicionar uma tag de anotação acima do objeto que deseja tornar parcelável.

Um exemplo da biblioteca está abaixo https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

Primeiro implemente o Parcelable em sua classe. Então passe um objeto como este.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

A sequência do pacote não é necessária, apenas a sequência precisa ser a mesma nas duas Atividades

REFERÊNCIA


2

Iniciar outra atividade a partir desta atividade passar parâmetros via Bundle Object

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

Recuperar em outra atividade (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

Isso é bom para tipos de dados simples. Mas se você quiser passar dados complexos entre as atividades, precisará serializá-los primeiro.

Aqui temos o modelo de funcionário

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Você pode usar o Gson lib fornecido pelo google para serializar dados complexos como este

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
    String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);

2

Na cidade Koltin

Adicione a extensão kotlin no seu build.gradle.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

Em seguida, crie sua classe de dados assim.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

Passar Objeto com Intenção

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

Obter objeto com intenção

val sample = intent.getParcelableExtra("id")

Ainda é experimental?
ShadeToD 28/06/19

2

A maneira mais fácil e java de fazer é: implemente serializável em sua classe pojo / model

Recomendado para Android para visualização do desempenho: torne o modelo parcelável


1

O mais simples seria usar apenas o seguinte em que o item é uma sequência:

intent.putextra("selected_item",item)

Para receber:

String name = data.getStringExtra("selected_item");

3
seu para string, número inteiro e etc apenas, mas eu quero o objeto e usando o objeto estático é apenas possível.
UMAR
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.