Вот подборка самых распространенных способов достижения этой цели :
- Отправка данных внутри цели
- Статические поля
- 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
interface . Его сложнее реализовать, но он значительно увеличил скорость по сравнению с Serializable
.
Обмен данными без сохранения на диске
Можно обмениваться данными между действиями, сохраняя их в памяти, учитывая, что в большинстве случаев обе операции выполняются в одном и том же процессе.
Примечание: иногда, когда пользователь покидает вашу деятельность (не выходя из нее), Android может решить убить ваше приложение. В таком сценарии у меня были случаи, когда Android пытался запустить последнее действие, используя намерение, предоставленное до того, как приложение было убито. В этом случае данные, хранящиеся в единственном экземпляре (или у вас, или Application
), исчезнут, и могут случиться плохие вещи. Чтобы избежать таких случаев, вы либо сохраняете объекты на диск, либо проверяете данные перед их использованием, чтобы убедиться, что они действительны.
Используйте класс Singleton
Есть класс для хранения данных:
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 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);
Вы можете или не можете передавать идентификатор объекта, используя дополнительные функции намерения. Все зависит от вашей конкретной проблемы.
Сохранять объекты на диске
Идея состоит в том, чтобы сохранить данные на диске перед запуском другого действия.
Преимущества: вы можете запускать действие из других мест и, если данные уже сохранены, оно должно работать просто отлично.
Недостатки: это громоздко и требует больше времени для реализации. Требуется больше кода и, следовательно, больше шансов на появление ошибок. Это также будет намного медленнее.
Некоторые способы сохранения объектов включают в себя: