Oto zestawienie najczęstszych sposobów osiągnięcia tego celu :
- Wysyłaj dane w sposób zamierzony
- Pola statyczne
- HashMap of
WeakReferences
- Zachowaj obiekty (sqlite, preferencje udostępniania, plik itp.)
TL; DR : istnieją dwa sposoby udostępniania danych: przekazywanie danych do dodatków intencji lub zapisywanie ich gdzie indziej. Jeśli dane są prymitywne, ciągi lub obiekty zdefiniowane przez użytkownika: wyślij je jako część zamierzonych dodatków (obiekty zdefiniowane przez użytkownika muszą zostać zaimplementowane Parcelable
). Jeśli przekazujesz złożone obiekty, zapisz instancję w singletonie w innym miejscu i uzyskaj do nich dostęp z uruchomionej aktywności.
Kilka przykładów tego, jak i dlaczego wdrożyć każde podejście:
Wysyłaj dane wewnątrz intencji
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
W sprawie drugiej aktywności:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
Użyj tej metody, jeśli przekazujesz prymitywne dane lub ciągi . Możesz także przekazywać obiekty, które implementują Serializable
.
Choć kuszące, powinieneś pomyśleć dwa razy przed użyciem Serializable
: jest podatne na błędy i strasznie powolne. Więc ogólnie: trzymaj się z daleka,Serializable
jeśli to możliwe. Jeśli chcesz przekazać złożone obiekty zdefiniowane przez użytkownika, spójrz na Parcelable
interfejs . Jest trudniejszy do wdrożenia, ale w porównaniu do niego ma znaczny wzrost prędkości Serializable
.
Udostępniaj dane bez utrwalania się na dysku
Możliwe jest współdzielenie danych między działaniami poprzez zapisanie ich w pamięci, biorąc pod uwagę, że w większości przypadków oba działania przebiegają w tym samym procesie.
Uwaga: czasami, gdy użytkownik opuści Twoją aktywność (bez wychodzenia z niej), Android może zdecydować o zabiciu Twojej aplikacji. W takim scenariuszu napotkałem przypadki, w których Android próbuje uruchomić ostatnią aktywność, wykorzystując zamiar podany przed śmiercią aplikacji. W takich przypadkach dane przechowywane w singletonie (twoje lub Application
) znikną i mogą się zdarzyć złe rzeczy. Aby uniknąć takich przypadków, należy utrwalić obiekty na dysku lub sprawdzić dane przed ich użyciem, aby upewnić się, że są prawidłowe.
Użyj klasy singleton
Poproś klasę, aby przechowała dane:
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;}
}
Z rozpoczętej działalności:
String data = DataHolder.getInstance().getData();
Użyj singletonu aplikacji
Singleton aplikacji to instancja android.app.Application
tworzona podczas uruchamiania aplikacji. Możesz podać niestandardowy, rozszerzając 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;}
}
Przed rozpoczęciem działania:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Następnie z rozpoczętej działalności:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Pola statyczne
Pomysł jest zasadniczo taki sam jak singleton, ale w tym przypadku zapewniasz statyczny dostęp do danych:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
Z rozpoczętej działalności:
String data = DataHolder.getData();
HashMap of WeakReferences
Ten sam pomysł, ale zezwalający śmieciarzowi na usuwanie niepowiązanych obiektów (np. Gdy użytkownik zakończy działanie):
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();
}
}
Przed rozpoczęciem działania:
DataHolder.getInstance().save(someId, someObject);
Z rozpoczętej działalności:
DataHolder.getInstance().retrieve(someId);
Możliwe, że nie musisz podawać identyfikatora obiektu przy użyciu dodatków intencji. Wszystko zależy od konkretnego problemu.
Utrwalaj obiekty na dysku
Chodzi o to, aby zapisać dane na dysku przed uruchomieniem innej czynności.
Zalety: możesz uruchomić działanie z innych miejsc, a jeśli dane są już utrwalone, powinno działać dobrze.
Wady: uciążliwe i zajmuje więcej czasu. Wymaga więcej kodu, a tym samym większej szansy na wprowadzenie błędów. Będzie też znacznie wolniej.
Niektóre sposoby utrwalania obiektów obejmują: