Aqui está uma compilação das maneiras mais comuns de conseguir isso :
- Enviar dados dentro da intenção
- Campos estáticos
- HashMap de
WeakReferences
- Persistir objetos (sqlite, compartilhar preferências, arquivo etc.)
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
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
Na segunda atividade:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
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 na Parcelable
interface . É mais difícil de implementar, mas possui ganhos de velocidade consideráveis em comparação com Serializable
.
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:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
Da atividade lançada:
String data = DataHolder.getInstance().getData();
Usar aplicativo singleton
O aplicativo singleton é uma instância android.app.Application
criada quando o aplicativo é iniciado. Você pode fornecer um personalizado estendendo Application
:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Antes de iniciar a atividade:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Em seguida, a partir da atividade lançada:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Campos estáticos
A ideia é basicamente a mesma que o singleton, mas nesse caso você fornece acesso estático aos dados:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
Da atividade lançada:
String data = DataHolder.getData();
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):
public class DataHolder {
Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();
void save(String id, Object object) {
data.put(id, new WeakReference<Object>(object));
}
Object retrieve(String id) {
WeakReference<Object> objectWeakReference = data.get(id);
return objectWeakReference.get();
}
}
Antes de iniciar a atividade:
DataHolder.getInstance().save(someId, someObject);
Da atividade lançada:
DataHolder.getInstance().retrieve(someId);
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: