Ecco una raccolta dei modi più comuni per raggiungere questo obiettivo :
- Invia dati con intento
- Campi statici
- HashMap di
WeakReferences
- Oggetti persistenti (sqlite, preferenze di condivisione, file, ecc.)
TL; DR : ci sono due modi per condividere i dati: passare i dati negli extra dell'intento o salvarli da qualche altra parte. Se i dati sono primitivi, stringhe o oggetti definiti dall'utente: inviarli come parte degli extra di intento (gli oggetti definiti dall'utente devono implementare Parcelable
). Se si passano oggetti complessi, salvare un'istanza in un singleton da qualche altra parte e accedervi dall'attività avviata.
Alcuni esempi di come e perché implementare ciascun approccio:
Invia dati con intenti
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
Sulla seconda attività:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
Utilizzare questo metodo se si stanno passando dati o stringhe primitivi . Puoi anche passare oggetti che implementano Serializable
.
Anche se allettante, dovresti pensarci due volte prima dell'uso Serializable
: è soggetto a errori e orribilmente lento. Quindi in generale: stai lontano daSerializable
se possibile. Se vuoi passare oggetti complessi definiti dall'utente, dai un'occhiata Parcelable
all'interfaccia . È più difficile da implementare, ma ha notevoli guadagni di velocità rispetto a Serializable
.
Condividi i dati senza persistere sul disco
È possibile condividere i dati tra le attività salvandole in memoria dato che, nella maggior parte dei casi, entrambe le attività vengono eseguite nello stesso processo.
Nota: a volte, quando l'utente lascia la tua attività (senza chiuderla), Android può decidere di terminare l'applicazione. In tale scenario, ho riscontrato casi in cui Android tenta di avviare l'ultima attività utilizzando l'intento fornito prima che l'app venisse uccisa. In questi casi, i dati memorizzati in un singleton (o tuo o Application
) spariranno e potrebbero accadere cose brutte. Per evitare tali casi, è necessario persistere oggetti sul disco o controllare i dati prima di utilizzarli per assicurarsi che siano validi.
Usa una classe singleton
Avere una classe per contenere i dati:
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;}
}
Dall'attività avviata:
String data = DataHolder.getInstance().getData();
Usa l'applicazione singleton
L'applicazione singleton è un'istanza di android.app.Application
cui viene creata all'avvio dell'app. Puoi fornirne uno personalizzato 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;}
}
Prima di avviare l'attività:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Quindi, dall'attività avviata:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Campi statici
L'idea è sostanzialmente la stessa del singleton, ma in questo caso fornisci accesso statico ai dati:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
Dall'attività avviata:
String data = DataHolder.getData();
HashMap di WeakReferences
Stessa idea, ma consentendo al garbage collector di rimuovere oggetti senza riferimento (ad es. Quando l'utente abbandona l'attività):
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();
}
}
Prima di avviare l'attività:
DataHolder.getInstance().save(someId, someObject);
Dall'attività avviata:
DataHolder.getInstance().retrieve(someId);
Potrebbe essere necessario o meno passare l'ID oggetto utilizzando gli extra dell'intento. Tutto dipende dal tuo problema specifico.
Persistere gli oggetti sul disco
L'idea è di salvare i dati sul disco prima di avviare l'altra attività.
Vantaggi: è possibile avviare l'attività da altri luoghi e, se i dati sono già persistiti, dovrebbe funzionare bene.
Svantaggi: è ingombrante e richiede più tempo per essere implementato. Richiede più codice e quindi maggiori possibilità di introdurre bug. Sarà anche molto più lento.
Alcuni dei modi per mantenere gli oggetti includono: