Eu tenho uma atividade que é a principal atividade usada em todo o aplicativo e possui várias variáveis. Eu tenho duas outras atividades que eu gostaria de poder usar os dados da primeira atividade. Agora eu sei que posso fazer algo assim:
GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();
No entanto, quero compartilhar muitas variáveis e algumas podem ser bastante grandes, por isso não quero criar cópias delas como acima.
Existe uma maneira de obter e alterar diretamente as variáveis sem usar os métodos get e set? Lembro-me de ler um artigo no site de desenvolvimento do Google dizendo que isso não é recomendado para o desempenho no Android.
Respostas:
Aqui está uma compilação das maneiras mais comuns de conseguir isso :
WeakReferences
TL; DR : existem duas maneiras de compartilhar dados: passar dados nos extras da intenção ou salvá-los em outro lugar. Se os dados forem primitivos, Strings ou objetos definidos pelo usuário: envie-os como parte dos extras de intenção (os objetos definidos pelo usuário devem ser implementados
Parcelable
). Se passar objetos complexos, salve uma instância em um singleton em outro lugar e acesse-os a partir da atividade iniciada.Alguns exemplos de como e por que implementar cada abordagem:
Enviar dados dentro das intenções
Na segunda atividade:
Use este método se estiver passando dados primitivos ou Strings . Você também pode passar objetos que implementam
Serializable
.Embora tentador, você deve pensar duas vezes antes de usar
Serializable
: é propenso a erros e terrivelmente lento. Então, em geral: fique longe,Serializable
se possível. Se você deseja transmitir objetos complexos definidos pelo usuário, dê uma olhada naParcelable
interface . É mais difícil de implementar, mas possui ganhos de velocidade consideráveis em comparação comSerializable
.Compartilhe dados sem persistir no disco
É possível compartilhar dados entre as atividades salvando-os na memória, pois, na maioria dos casos, as duas atividades são executadas no mesmo processo.
Nota: às vezes, quando o usuário sai de sua atividade (sem sair dela), o Android pode decidir matar seu aplicativo. Nesse cenário, experimentei casos em que o Android tenta iniciar a última atividade usando a intenção fornecida antes da morte do aplicativo. Nesses casos, os dados armazenados em um singleton (seu ou
Application
) desaparecerão e poderão ocorrer coisas ruins. Para evitar esses casos, você persiste objetos no disco ou verifica os dados antes de usá-los para garantir sua validade.Use uma classe singleton
Tenha uma classe para armazenar os dados:
Da atividade lançada:
Usar aplicativo singleton
O aplicativo singleton é uma instância
android.app.Application
criada quando o aplicativo é iniciado. Você pode fornecer um personalizado estendendoApplication
:Antes de iniciar a atividade:
Em seguida, a partir da atividade lançada:
Campos estáticos
A ideia é basicamente a mesma que o singleton, mas nesse caso você fornece acesso estático aos dados:
Da atividade lançada:
HashMap de
WeakReferences
A mesma ideia, mas permitindo que o coletor de lixo remova objetos não referenciados (por exemplo, quando o usuário sai da atividade):
Antes de iniciar a atividade:
Da atividade lançada:
Você pode ou não ter que passar a identificação do objeto usando os extras da intenção. Tudo depende do seu problema específico.
Persistir objetos no disco
A idéia é salvar os dados no disco antes de iniciar a outra atividade.
Vantagens: você pode iniciar a atividade de outros lugares e, se os dados já persistirem, devem funcionar bem.
Desvantagens: é complicado e leva mais tempo para ser implementado. Requer mais código e, portanto, mais chance de introduzir bugs. Também será muito mais lento.
Algumas das maneiras de persistir objetos incluem:
fonte
setResult
método Além disso, nesse caso, a atividade secundária deve ser chamada usando ostartActivityForResult
métodoActivity
todo e, em suaonCreate()
verificação, qualquer campo estático do singleton que você preenche ao iniciar o aplicativo. Se esse campo estiver vazio, volte à atividade inicial usandoFLAG_ACTIVITY_CLEAR_TASK
ou aBroadcastReceiver
para eliminar outras atividades.O que você pode usar:
O que você escolhe depende de suas necessidades. Provavelmente você usará mais de uma maneira quando tiver "muitas"
fonte
MAIN
ação. Após a morte do processo, você reinicia qualquer atividade aberta pela última vez, que pode ser uma página de detalhes em algum lugar profundo do aplicativo.Faça o que o google ordena que você faça! aqui: http://developer.android.com/resources/faq/framework.html#3
fonte
Isso não faz uma cópia (especialmente com String , mas mesmo os objetos são passados pelo valor da referência, não o próprio objeto, e os getter são bons de usar - sem dúvida melhor do que outros meios, porque são comuns e bem entendido). Os "mitos de desempenho" mais antigos, como não usar getters e setters, ainda têm algum valor, mas também foram atualizados nos documentos .
Mas se você não quiser fazer isso, também poderá tornar as variáveis públicas ou protegidas no GlobalState e acessá-las diretamente. E você pode criar um singleton estático como o objeto Aplicativo JavaDoc indica :
O uso de dados de intenção , como outras respostas aqui indicadas, é outra maneira de transmitir dados, mas geralmente é usado para dados menores e tipos simples. Você pode transmitir dados maiores / mais complexos, mas é mais envolvido do que apenas usar um único estático. O objeto Application ainda é o meu favorito para compartilhar dados não persistentes maiores / mais complexos entre os componentes de aplicativos Android (porque possui um ciclo de vida bem definido em um aplicativo Android).
Além disso, como outros observaram, se os dados ficarem muito complexos e precisarem ser persistentes , você poderá usar o SQLite ou o sistema de arquivos também.
fonte
Você pode estender a classe Application e marcar em qualquer objeto que desejar, eles estarão disponíveis em qualquer lugar do seu aplicativo
fonte
Existe uma maneira nova e melhor de compartilhar dados entre atividades, e é o LiveData . Observe em particular esta citação na página do desenvolvedor do Android:
A implicação disso é enorme - qualquer dado de modelo pode ser compartilhado em uma classe singleton comum dentro de um
LiveData
wrapper. Ele pode ser injetado das atividades nos respectivosViewModel
para fins de testabilidade. E você não precisa mais se preocupar com referências fracas para evitar vazamentos de memória.fonte
Usando o hashmap da abordagem de referência fraca, descrito acima, e em http://developer.android.com/guide/faq/framework.html parece problemático para mim. Como as entradas inteiras são recuperadas, não apenas o valor do mapa? Em que escopo você o aloca? Como a estrutura está no controle do ciclo de vida da atividade, ter uma das atividades participantes próprias corre o risco de erros de tempo de execução quando o proprietário é destruído antes de seus clientes. Se o Aplicativo for o proprietário, alguma Atividade deverá remover explicitamente a entrada para evitar que o mapa de hash se segure nas entradas com uma chave válida e uma referência fraca coletada potencialmente prejudicada. Além disso, o que um cliente deve fazer quando o valor retornado para uma chave é nulo?
Parece-me que um WeakHashMap de propriedade do Aplicativo ou dentro de um singleton é uma escolha melhor. Um valor no mapa é acessado por meio de um objeto-chave e, quando não existem referências fortes à chave (ou seja, todas as atividades são feitas com a chave e para o que ele mapeia), o GC pode recuperar a entrada do mapa.
fonte
Existem várias maneiras de compartilhar dados entre atividades
1: Passando dados entre atividades usando Intent
2: Usando a palavra-chave estática, defina a variável como estática pública e use qualquer parte do projeto
use em qualquer lugar do projeto usando classname.variableName;
3: Usando banco de dados
mas seu processo demorado, você deve usar a consulta para inserir dados e iterar os dados usando o cursor quando necessário. Mas não há chance de perder dados sem limpar o cache.
4: Usando preferências compartilhadas
muito mais fácil que o banco de dados. mas há algumas limitações que você não pode salvar objetos ArrayList, List e custome.
5: Crie o getter setter na classe Aplication e acesse qualquer local do projeto.
aqui definir e obter de atividades
fonte
Bem, eu tenho algumas idéias, mas não sei se elas são o que você está procurando.
Você pode usar um serviço que armazena todos os dados e depois vincular suas atividades ao serviço para recuperação de dados.
Ou empacote seus dados em um serializável ou parcelável e anexe-os a um pacote configurável e passe o pacote entre atividades.
Esse pode não ser o que você está procurando, mas você também pode tentar usar Preferências compartilhadas ou uma preferência em geral.
De qualquer maneira, deixe-me saber o que você decide.
fonte
Supondo que você esteja chamando a atividade dois da atividade um usando um Intent.
Você pode passar os dados com o intent.putExtra (),
Leve isso para sua referência. Enviando matrizes com Intent.putExtra
Espero que seja o que você quer.
fonte
Se sua intenção é chamar outras atividades da atividade atual, você deve usar intenções . Seu foco pode ser menos em dados persistentes do que em compartilhá-los conforme a necessidade.
No entanto, se você realmente precisar persistir com esses valores, poderá persisti-los em algum tipo de arquivo de texto estruturado ou banco de dados no armazenamento local. Um arquivo de propriedades, arquivo XML ou arquivo JSON pode armazenar seus dados e ser facilmente analisados durante a criação da atividade. Não esqueça também que você possui SQLite em todos os dispositivos Android, para armazená-los em uma tabela de banco de dados. Você também pode usar um mapa para armazenar pares de valores-chave e serializar o mapa para armazenamento local, mas isso pode ser muito complicado para ser útil para estruturas de dados simples.
fonte
Todas as respostas acima mencionadas são ótimas ... Estou apenas adicionando uma que ninguém mencionou ainda sobre persistência de dados por meio de atividades e que é usar o banco de dados SQLite Android embutido para persistir dados relevantes ... Na verdade, você pode colocar seu databaseHelper no estado do aplicativo e chame-o conforme necessário durante as atividades ativadas .. Ou apenas faça uma classe auxiliar e faça as chamadas ao banco de dados quando necessário ... Apenas adicionando outra camada para você considerar ... Mas todas as outras respostas seriam suficientes bem .. realmente apenas preferência
fonte
Exemplo de compartilhamento de dados entre atividades, passando um email após o login
"email" é o nome que pode ser usado para referenciar o valor da atividade que está sendo solicitada
1 Código na página de login
2 código na página inicial
fonte
E se você deseja trabalhar com objeto de dados, esses dois implementam muito importantes:
Serializable vs Parcelable
public class User implements Parcelable
confira mais aqui
fonte