Каков наилучший способ обмена данными между действиями?

У меня есть одно действие, которое является основным видом деятельности, используемым во всем приложении, и оно имеет ряд переменных. У меня есть два других вида деятельности, которые я хотел бы использовать в данных из первого действия. Теперь я знаю, что могу сделать что-то вроде этого:

GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();

Однако я хочу поделиться множеством переменных, а некоторые могут быть довольно большими, поэтому я не хочу создавать их копии, как показано выше.

Есть ли способ напрямую получать и изменять переменные без использования методов get и set? Я помню, как читал статью на сайте Google dev, в которой говорится, что это не рекомендуется для производительности на Android.

java,android,sharing,

203

Ответов: 13


434 ов

Вот компиляция наиболее распространенных способов достижения этого :

  • Отправлять данные внутри намерения
  • Статические поля
  • 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);

Вы можете или не должны передавать идентификатор объекта, используя дополнительные намерения. Все зависит от вашей конкретной проблемы.

Перенесение объектов на диск

Идея состоит в том, чтобы сохранить данные на диске перед запуском другого действия.

Преимущества: вы можете запускать деятельность из других мест, и если данные уже сохраняются, она должна работать нормально.

Недостатки: это громоздко и требует больше времени для реализации. Требуется больше кода и, следовательно, больше шансов ввести ошибки. Это также будет намного медленнее.

Некоторые из способов сохранения объектов включают в себя:


22

Что вы можете использовать:

  1. передача данных между действиями (как сказал Кристиан)
  2. используя класс с множеством статических переменных (поэтому вы можете вызывать их без экземпляра класса и без использования getter / setter)
  3. Использование базы данных
  4. Общие настройки

То, что вы выбираете, зависит от ваших потребностей. Вероятно, вы будете использовать более одного способа, когда у вас будет «много»,


16

Сделайте то, что вам нужно сделать Google! здесь: http://developer.android.com/resources/faq/framework.html#3

  • Примитивные типы данных
  • Непостоянные объекты
  • Singleton class - мой любимый: D
  • Публичное статическое поле / метод
  • HashMap of WeakReferences to Objects
  • Персистентные объекты (настройки приложений, файлы, contentProviders, SQLite DB)

уя 14

«Тем не менее, я хочу поделиться большим количеством переменных, а некоторые могут быть довольно большими, поэтому я не хочу создавать их копии, как показано выше».

Это не делает копию (особенно с String , но даже объекты передаются по значению ссылки, а не по самому объекту, и подобные getter'ы подходят для использования - возможно, лучше использовать, чем другие средства, потому что они являются общими и понятно хорошо). Более старые «мифы о производительности», такие как не использование геттеров и сеттеров, по-прежнему имеют определенную ценность, но также были обновлены в документах .

Но если вы не хотите этого делать, вы можете просто сделать переменные общедоступными или защищенными в GlobalState и получить к ним доступ напрямую. И вы можете сделать статический синглтон, поскольку объект Application JavaDoc указывает :

Как правило, нет необходимости в подклассе Application. В большинстве случаев статические синглтоны могут обеспечивать такую ??же функциональность более модульным способом. Если вашему singleton нужен глобальный контекст (например, для регистрации широковещательных приемников), функции для его получения может быть предоставлен контекст, который внутренне использует Context.getApplicationContext () при первом построении синглета.

Использование данных Intent , так как другие ответы здесь - это еще один способ передачи данных, но он обычно используется для небольших данных и простых типов. Вы можете передавать более сложные или более сложные данные, но это более активно, чем просто использование статического одиночного. Объект Application по-прежнему остается моим личным фаворитом для совместного использования более крупных / более сложных несовместимых данных между компонентами Android (хотя он имеет четко определенный жизненный цикл в приложении для Android).

Кроме того, как отмечали другие, если данные становятся очень сложными и должны быть постоянными, вы также можете использовать SQLite или файловую систему.


Вы можете расширить Application класс и бирку на любые объекты , которые вы хотите там, они будут доступны в любом месте в вашем приложении

Java, Android, обмен,
Похожие вопросы