Ось компіляція найпоширеніших способів досягнення цього :
- Надіслати дані всередині наміру
- Статичні поля
- HashMap of
WeakReferences
- Зберігаються об'єкти (sqlite, параметри спільного доступу, файл тощо)
TL; DR : Є два способи обміну даними: передача даних у додатки намірів або збереження їх десь в іншому місці. Якщо дані є примітивами, Strings або визначені користувачем об’єкти: надішліть їх як частину додаткових додатків (визначені користувачем об'єкти повинні реалізувати Parcelable
). Якщо передача складних об'єктів зберігає екземпляр у синглтоні десь ще та отримує доступ до них із запущеної діяльності.
Деякі приклади того, як і чому реалізувати кожен підхід:
Надіслати дані всередині намірів
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
Про другу діяльність:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
Використовуйте цей метод, якщо ви передаєте примітивні дані або Strings . Ви також можете передавати об'єкти, які реалізує Serializable
.
Хоча спокусливо, варто подумати двічі перед використанням Serializable
: вона схильна до помилок і жахливо повільна. Так загалом: тримайтеся подалі відSerializable
можливості, якщо це можливо. Якщо ви хочете передати складні визначені користувачем об’єкти, подивіться на Parcelable
інтерфейс . Це важче здійснити, але він має значне збільшення швидкості порівняно з Serializable
.
Обмінюйтесь даними без збереження на диску
Обмінюватися даними між видами діяльності можна, зберігаючи їх у пам'яті, враховуючи, що в більшості випадків обидві дії виконуються в одному процесі.
Примітка. Іноді, коли користувач залишає вашу діяльність (не відмовляючись від неї), Android може вирішити знищити вашу програму. У такому сценарії я переживав випадки, коли андроїд намагався запустити останню активність за допомогою намірів, передбачених до вбивства програми. У цьому випадку дані, що зберігаються в одиночному (або вашому, або Application
), не будуть втрачені, і погані речі можуть трапитися. Щоб уникнути подібних випадків, ви або зберігаєте об’єкти на диску або перевіряєте дані, перш ніж використовувати їх, щоб переконатися в їх дійсності.
Використовуйте однокласний клас
Майте клас для зберігання даних:
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;}
}
Із розпочатої діяльності:
String data = DataHolder.getInstance().getData();
Використовуйте додаток одиночний
Singleton - це екземпляр, android.app.Application
який створюється при запуску програми. Ви можете надати спеціальний, розширивши 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;}
}
Перш ніж розпочати діяльність:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Потім із запущеної діяльності:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Статичні поля
Ідея в основному така ж, як синглтон, але в цьому випадку ви надаєте статичний доступ до даних:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
Із розпочатої діяльності:
String data = DataHolder.getData();
HashMap of WeakReferences
Ця ж ідея, але дозволяючи сміттєзбірнику видаляти непов'язані об'єкти (наприклад, коли користувач припиняє діяльність):
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();
}
}
Перш ніж розпочати діяльність:
DataHolder.getInstance().save(someId, someObject);
Із розпочатої діяльності:
DataHolder.getInstance().retrieve(someId);
Ви можете або не повинні передати ідентифікатор об'єкта за допомогою додатків намірів. Все залежить від вашої конкретної проблеми.
Зберігайте об'єкти на диску
Ідея полягає у збереженні даних на диску перед запуском іншої діяльності.
Переваги: ви можете запускати діяльність з інших місць, і якщо дані вже зберігаються, вони повинні працювати чудово.
Недоліки: це громіздко і потребує більше часу на реалізацію. Потрібно більше коду і, отже, більше шансів ввести помилки. Це також буде набагато повільніше.
Деякі способи збереження об'єктів включають: