Зачем использовать Bundle, когда вы можете просто использовать приложение? - PullRequest
2 голосов
/ 20 октября 2011

Я читаю эту статью о том, как: правильно сохранить состояние переменной в Android , и мне напоминают, что я никогда не получал хороший ответ (и не могу найти его здесь), почемуЛучше бороться с Bundle (который не является ОГРОМНЫМ, но определенно имеет свои ограничения), а не просто всегда иметь приложение, переопределенное в вашем приложении, и просто хранить все свои постоянные элементы данных там.Есть ли риск утечки?Есть ли способ, которым память может быть освобождена неожиданно?Я просто не совсем уверен в этом ... он кажется, что это абсолютно надежный "чердак" для всех действий, и это идеальное место для хранения всего, что вы беспокоитесь, может быть сброшено, когда пользователь поворачивает устройство или приостанавливаетприложение.

Я не прав в этом?Хотелось бы получить некоторую ясность относительно того, каков истинный жизненный цикл памяти в Приложении.


Основываясь на ответах ниже, позвольте мне расширить мой вопрос.

Предположим, у меня естьприложение, которое ведет себя по-разному в зависимости от XML-файла, который загружается при запуске.

В частности, это приложение для сбора информации о пользователе, и в зависимости от настроек XML оно будет следовать по разным путям (сбор информации A, но не J, и предложение Survey P, за которым следует дополнительная возможность фотосъемки и т. д.)

В идеале мне не нужно хранить детали этого пути поведения в Связке (не дай бог) илибаза данных (тоже некрасивая, но не очень).Я бы загружал XML, обрабатывал его и удерживал приложение на этой структуре, чтобы я мог ссылаться на него, что делать дальше и как.Если приложение поставлено на паузу и приложение выпущено, это не слишком сложная задача - проверить наличие нулевого значения в моем объекте CustomFlow (который генерируется в соответствии с XML) и повторно создать его экземпляр.В любом случае, это не так часто случается.Будет ли это хорошим примером того, где Application является * лучшим инструментом?

Ответы [ 3 ]

4 голосов
/ 20 октября 2011

Вопрос о том, какой метод лучше, во многом зависит от того, какую информацию вы храните и к которой вам нужен доступ, и кому (какие компоненты, пакеты и т. Д.) Нужен доступ к этой информации.Кроме того, такие настройки, как launchMode и configChanges, которые изменяют жизненный цикл, могут помочь вам определить, какой метод лучше для вас.

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

В жизненном цикле приложения: Чуббард в основном правильно заявил, что приложение имеет тот же срок службы, что и компонент Singleton.Хотя они очень близки, есть небольшие отличия.Само приложение рассматривается ОС как ОС Singleton и остается активным до тех пор, пока активен ЛЮБОЙ компонент, включая AppWidget (который может существовать в другом приложении) или ContentResolver.

Все ваши компоненты в конечном итоге получают доступ к одному и тому же объекту, даже если они находятся в нескольких заданиях или процессах.Тем не менее, это не гарантируется, что это останется таким навсегда (поскольку приложение не является на самом деле синглтоном), и гарантируется только в Google Android, а не в переопределенных выпусках производителя.Это означает, что с некоторыми объектами в объекте приложения следует обращаться осторожно.

Ваш объект Application не умрет, если все ваши компоненты также не будут уничтожены.Тем не менее, Android имеет возможность убить любое количество компонентов.Это означает, что у вас никогда не будет гарантированно иметь Application объект, но если какой-либо из ваших компонентов жив, то есть Application, чтобы связать его с.

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

Что следует избегать в объекте приложения:

  • В соответствии с обычным, избегайте статических Context s.На самом деле, часто вам вообще не следует хранить здесь Context, потому что Application сам по себе Context.
  • Большинство методов здесь должны быть статическими, потому что вы не гарантированно получите тот же самый объект Application, даже если это крайне вероятно.
  • Если вы переопределите Application, типВаши данные и методы, хранящиеся здесь, помогут вам в дальнейшем определить, нужно ли вам создавать компонент Singleton или нет.
  • Drawables и его производные с наибольшей вероятностью могут «просочиться», если не позаботиться о них, поэтомуздесь также рекомендуется избегать ссылок на Drawables.
  • Состояние выполнения любого отдельного компонента.Это потому что, опять же, вы не гарантированно получите тот же самый объект Application.Кроме того, ни одно из событий жизненного цикла, которые происходят в Activity, не доступно здесь.

Вещи для хранения в Приложении (через Пакет)

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

Если у вас есть ContentProvider или BroadcastReceiver, это делает Application еще более идеальным, поскольку у них есть небольшие жизненные циклы, которыене «возобновляемый», как Activity или AppWidgetProvider, и теперь может получать доступ к этим данным или методам.

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

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

Вещи для хранения в Bundle, а не в приложении Состояние во время выполнения, которое зависит от наличия или состояния одного компонента или одного запуска компонента. Кроме того, все, что зависит от состояния отображения, ориентации или аналогичных служб Android, здесь не является предпочтительным. Это потому, что Application никогда не уведомляется об этих изменениях. Наконец, все, что зависит от уведомлений от этой системы Android, не должно размещаться здесь, например, реакция на события жизненного цикла.

И .... В другом месте

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

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

Помните, есть причина, по которой Android должен убивать ваши компоненты. И основная причина - память, а не обработка. Используя Приложение, как описано выше, и разрабатывая соответствующие методы для сохранения соответствующей информации, вы можете создавать более сильные приложения, которые важны для Системы, Пользователя, его родственных компонентов и других разработчиков. Использование информации, предоставленной всеми здесь, должно дать вам отличное руководство о том, как и когда расширять ваш Application.

Надеюсь, это поможет, FuzzicalLogic

3 голосов
/ 20 октября 2011

Я предпочитаю создавать подклассы Application и указывать на это свой манифест.Я думаю, что это нормальный способ кодирования Android, хотя архитекторы Android из Google считают, что для этого нужно использовать Singletons (eek).Синглтоны имеют то же время жизни, что и приложение, поэтому все, что к ним относится, относится к приложению, за исключением того, что синглтоны создают гораздо меньше беспорядка.По сути, они даже не используют связки.Я думаю, что использование подкласса Application значительно ускорило программирование в Android с гораздо меньшими хлопотами.

Теперь о недостатках.Ваше приложение может быть закрыто, если телефону требуется больше памяти или ваше приложение переходит в фоновый режим.Это может означать, что пользователь ответил на звонок или проверил свою электронную почту.Например, допустим, у вас есть действие, которое заставляет пользователя войти в систему для получения токена, который другие действия будут использовать для выполнения вызовов на сервере.Это то, что вы можете хранить в своем сервисном объекте (не в Android-сервисе, а в классе, который отправляет сетевые вызовы на ваш сервер), который вы храните в своем подклассе Application.Хорошо, если ваше приложение будет закрыто, вы потеряете этот токен, и когда пользователь нажмет кнопку «Назад», ваш пользователь может вернуться к действию, в котором предполагается, что вы уже прошли проверку подлинности и что ваш класс обслуживания не работает.

Итакчто ты можешь сделать?Продолжать использовать Bundle ужас?Нет, вы не могли бы легко хранить токены безопасности в комплекте (хотя могут быть некоторые проблемы с безопасностью в зависимости от того, как это работает для вашего приложения), или вам придется кодировать свою деятельность, чтобы не принимать определенное состояние, в котором находится приложение. Iпришлось проверить на предмет потери токена и перенаправить пользователя обратно на экран входа в систему, когда это произойдет.Но, в зависимости от состояния, которое содержит объект Application, это может быть сложно.Но имейте в виду, что ваше приложение может знать, когда оно завершает работу, и сохранять свое внутреннее состояние в пакете. Это, по крайней мере, позволяет вам сохранять ваши Объекты в памяти в течение 99% времени вашего Приложения и сохранять / восстанавливать только тогда, когда оно отключается, а не постоянно сериализовать и десериализовать с помощью кода котельной пластины всякий раз, когда вы переходите между операциями ,Использование приложения позволяет вам централизовать то, как ваша программа может быть запущена и остановлена, и, поскольку она обычно живет дольше, чем какое-либо одно действие, это может уменьшить необходимость для программы восстанавливать кишки вашего приложения, когда пользователь перемещается между действиями.Это делает ваш код чище, не допуская сведений о приложении из каждого действия, снижает накладные расходы, если ваше приложение уже построено, разделяет общие экземпляры / код и позволяет восстанавливать действия, не теряя при этом всю вашу программу.Все хорошие программы нуждаются в централизованном хабе, который является ядром, а приложение подклассов дает вам это, позволяя вам участвовать в жизненном цикле Android.

Мой личный фаворит - использовать http://flexjson.sourceforge.net/ для сериализации моей Javaобъекты в пакеты как JSON, если мне нужно отправить объекты вокруг или сохранить их.Гораздо проще, чем запись в sqlite DB, когда все, что вам нужно сделать, это сохранить данные.И хорошо, когда вы отправляете данные между двумя Деятельностями, используя объекты вместо разбитых на части примитивов.

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

2 голосов
/ 20 октября 2011

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

Длинный ответ:

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

Возможность восстановить свое состояние из пакета (который Android сохранит для вас, когда ваш процесс исчезнет) - это то, как Android поддерживает миф о многозадачности. Если вы не выгружаете состояние своей активности в пакет каждый раз, когда вызывается onSaveInstanceState, ваше приложение будет выглядеть так, как будто оно было перезапущено, когда пользователь, возможно, только что отключился на секунду. Это может быть особенно тревожным, когда система ограничена в ресурсах, так как система должна будет чаще завершать процессы, чтобы устройство работало быстро

Почему приложение может быть плохим

Приложение на самом деле не получает возможности сохранить какие-либо свои данные, если процесс остановлен. У него действительно есть метод onDestroy, но документы скажут вам, что это фактически никогда не вызывается системой на реальном устройстве. Это означает, что в упомянутом выше ограниченном случае любая побочная информация о том, что происходит в Деятельности (если вы сохранили ее в Приложении), будет потеряна, если процесс завершится.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...