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

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

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

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

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

13 Solutions collect form web for “Каков наилучший способ обмена данными между действиями?”

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

  • Отправлять данные внутри намерения
  • Статические поля
  • HashMap of 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 может решить убить ваше приложение. В таком сценарии у меня были случаи, когда андроид пытается запустить последнее действие, используя намерение, представленное до того, как приложение было убито. В этом случае данные, хранящиеся в одноэлементном (либо вашем, либо Application ), исчезнут, и могут произойти плохие вещи. Чтобы избежать таких случаев, вы либо сохраняете объекты на диске, либо проверяете данные перед их использованием, чтобы убедиться, что они действительны.

Использовать одноэлементный class

У вас есть class для хранения данных:

 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

Приложение 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 of WeakReferences

Такая же идея, но позволяет сборщику мусора удалять объекты без ссылок (например, когда пользователь прекращает действие):

 public class DataHolder { Map> data = new HashMap>(); void save(String id, Object object) { data.put(id, new WeakReference(object)); } Object retrieve(String id) { WeakReference objectWeakReference = data.get(id); return objectWeakReference.get(); } } 

Перед началом деятельности:

 DataHolder.getInstance().save(someId, someObject); 

От запущенной деятельности:

 DataHolder.getInstance().retrieve(someId); 

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

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

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

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

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

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

  • Сохраните их в общих настройках
  • Сохраните их в базе данных sqlite
  • Сохраните их в файл (я бы избегал этого)

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

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

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

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

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

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

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

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

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

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

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

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

Использование хешмапа слабого ссылочного подхода, описанного выше, и в http://developer.android.com/guide/faq/framework.html кажется мне проблематичным. Как восстанавливаются целые записи, а не только значение карты? В какой области вы его распределяете? Поскольку инфраструктура контролирует жизненный цикл Activity, при наличии одной из участвующих в ней Деяний, она подвергает риску ошибки времени выполнения, когда владелец уничтожается до своих клиентов. Если приложение принадлежит ему, некоторые действия должны явно удалить запись, чтобы избежать того, чтобы hash-файл не включался в записи с действительным ключом и потенциально сфальсифицированной собранной слабой ссылкой. Кроме того, что должен делать клиент, когда значение, возвращаемое для ключа, равно null?

Мне кажется, что WeakHashMap, принадлежащий Приложению или в рамках одного сингла, является лучшим выбором. Доступ к значению на карте осуществляется с помощью ключевого объекта, и когда нет сильных ссылок на ключ (т.е. все действия выполняются с ключом и на что он сопоставляется), GC может восстановить запись карты.

Ну, у меня есть несколько идей, но я не знаю, являются ли они тем, что вы ищете.

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

Или упакуйте свои данные в сериализуемую или parsingчивую информацию и прикрепите их к набору и передайте пакет между действиями.

Это может быть совсем не то, что вы ищете, но вы также можете попробовать использовать SharedPreferences или предпочтение в целом.

В любом случае, дайте мне знать, что вы решите.

Предполагая, что вы вызываете активность два из одного действия с использованием намерения.
Вы можете передавать данные с помощью намерения.putExtra (),

Возьмите это для справки. Передача массивов с помощью Intent.putExtra

Надеюсь, это то, что вы хотите.

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

Однако, если вам действительно необходимо сохранить эти значения, вы можете сохранить их в каком-то структурированном текстовом файле или базе данных на локальном хранилище. Файл свойств, файл XML или файл JSON могут хранить ваши данные и легко анализироваться во время создания активности. Не забывайте также, что у вас есть SQLite на всех устройствах Android, поэтому вы можете хранить их в таблице базы данных. Вы также можете использовать карту для хранения пар ключ-значение и сериализации карты для локального хранилища, но это может быть слишком громоздким, чтобы быть полезным для простых структур данных.

Все вышеперечисленные ответы велики … Я просто добавлю, что никто еще не упомянул о сохраняющихся данных через действия, а также использовать встроенную базу данных Androidite SQL для сохранения соответствующих данных … Фактически вы можете разместить свои databaseHelper в состоянии приложения и вызывать его по мере необходимости во всех активах .. Или просто создайте вспомогательный class и сделайте вызовы БД при необходимости … Просто добавив еще один слой для вас, чтобы рассмотреть … Но все остальные ответы были бы достаточными а также .. Действительно просто предпочтение

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

«email» – это имя, которое может использоваться для ссылки на значение для запрашиваемой деятельности

1 Код на странице входа

 Intent openLoginActivity = new Intent(getBaseContext(), Home.class); openLoginActivity.putExtra("email", getEmail); 

2 на домашней странице

 Bundle extras = getIntent().getExtras(); accountEmail = extras.getString("email"); 

Существуют различные способы обмена данными между действиями

1: Передача данных между действиями с использованием Intent

 Intent intent=new Intent(this, desirableActivity.class); intent.putExtra("KEY", "Value"); startActivity(intent) 

2: Используя статическое ключевое слово, определите переменную как общедоступную статическую и используйте любое место в проекте

  public static int sInitialValue=0; 

использовать в любом месте проекта, используя classname.variableName;

3: Использование базы данных

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

4: Использование общих настроек

намного проще, чем firebase database. но есть некоторые ограничения, вы не можете сохранить объекты ArrayList, List и custome.

5: Создайте сеттер-получатель в classе Aplication и получите доступ к любому проекту в проекте.

  private String data; public String getData() { return data; } public void setData(String data) { this.data = data; } 

здесь установить и получить от деятельности

  ((YourApplicationClass)getApplicationContext()).setData("abc"); String data=((YourApplicationClass)getApplicationContext()).getData(); 

И если вы хотите работать с объектом данных, это два очень важных:

Сериализуемый против Parcelable

  • Serializable – это интерфейс маркера, который подразумевает, что пользователь не может сортировать данные в соответствии с их требованиями. Поэтому, когда объект реализует Serializable Java, он автоматически сериализует его.
  • Parcelable – собственный протокол сериализации Android. В Parcelable разработчики пишут собственный код для маршалинга и parsingки. Таким образом, он создает меньше мусорных объектов по сравнению с сериализацией
  • Производительность Parcelable очень высока по сравнению с Serializable из-за его пользовательской реализации. Очень рекомендуется использовать Parcelable имплантацию при сериализации объектов в android.

public class User implements Parcelable

проверьте больше здесь

  • Как добавить параметры в HTTP GET-запрос в Android?
  • В чем разница между статическим методом и нестатическим методом?
  • Как выполнить java .class из командной строки
  • JSON Array итерация в Android / Java
  • Что такое Runtime.getRuntime (). TotalMemory () и freeMemory ()?
  • Можно ли использовать Java 8 для разработки Android?
  • Не удалось конвертировать в формат Dalvik: невозможно выполнить dex: Java heap space
  • Каковы все различные способы создания объекта в Java?
  • Установка значения свойства Singleton в Firebase Listener
  • Обнаружение долгой печати с помощью Android
  • Android ListView заголовки
  • Давайте будем гением компьютера.