Вот компиляция наиболее распространенных способов достижения этого :
- Отправлять данные внутри намерения
- Статические поля
- HashMap из
WeakReferences
- Персистентные объекты (sqlite, общие настройки, файлы и т. Д.)
TL; DR : существует два способа совместного использования данных: передача данных в дополнительных целях или сохранение их в другом месте. Если данные являются примитивами, строками или определенными пользователем объектами: отправьте его как часть дополнительных намерений (должны быть реализованы определенные пользователем объекты 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");
Используйте этот метод, если вы передаете примитивные данные или строки . Вы также можете передавать объекты, которые реализуются Serializable
.
Хотя вы соблазнительны, вы должны подумать дважды, прежде чем использовать Serializable
: это склонность к ошибкам и ужасно медленная. Так что вообще: держитесь подальше,Serializable
если это возможно. Если вы хотите передать сложные пользовательские объекты, взгляните на Parcelable
интерфейс . Его сложнее реализовать, но он имеет значительный прирост скорости по сравнению с Serializable
.
Совместное использование данных без сохранения на диске
Можно передавать данные между действиями, сохраняя их в памяти, учитывая, что в большинстве случаев оба действия выполняются в одном процессе.
Примечание: иногда, когда пользователь покидает вашу деятельность (не оставляя ее), Android может решить убить ваше приложение. В таком сценарии у меня были случаи, когда андроид пытается запустить последнее действие, используя намерение, представленное до того, как приложение было убито. В этом случае данные, хранящиеся в одноэлементном (либо вашем, либо ), исчезнут, и могут произойти плохие вещи. Чтобы избежать таких случаев, вы либо сохраняете объекты на диске, либо проверяете данные перед их использованием, чтобы убедиться, что они действительны.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();
От запущенной деятельности:
android.app.Application
Использовать приложение singleton
Приложение singleton - это экземпляр, 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 String setData(String data) {DataHolder.data = data;}
}
От запущенной деятельности:
String data = DataHolder.getData();
HashMap из 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);
Вы можете или не должны передавать идентификатор объекта, используя дополнительные намерения. Все зависит от вашей конкретной проблемы.
Перенесение объектов на диск
Идея состоит в том, чтобы сохранить данные на диске перед запуском другого действия.
Преимущества: вы можете запускать деятельность из других мест, и если данные уже сохраняются, она должна работать нормально.
Недостатки: это громоздко и требует больше времени для реализации. Требуется больше кода и, следовательно, больше шансов ввести ошибки. Это также будет намного медленнее.
Некоторые из способов сохранения объектов включают в себя:
- Сохраните их в общих настройках
- Сохраните их в базе данных sqlite
- Сохраните их в файл (я избегу этого)