getApplication () против getApplicationContext () - PullRequest
400 голосов
/ 16 февраля 2011

Я не смог найти удовлетворительного ответа на этот вопрос, поэтому здесь мы идем: что за дело с Activity/Service.getApplication() и Context.getApplicationContext()?

В нашем приложении оба возвращают один и тот же объект.В ActivityTestCase, однако, насмешка над приложением заставит getApplication() вернуться с насмешкой, но getApplicationContext по-прежнему будет возвращать другой экземпляр контекста (один введенный Android).Это ошибка?Это нарочно?

Я даже не понимаю разницу во-первых.Есть ли случаи за пределами набора тестов, когда оба вызова могут возвращаться с разными объектами?Когда и почему?Кроме того, почему getApplication определено для Activity и Service, но не для Context?Разве не всегда должен быть действительный экземпляр приложения, доступный из в любом месте ?

Ответы [ 4 ]

354 голосов
/ 20 июля 2011

Очень интересный вопрос.Я думаю, что это в основном семантическое значение, а также может быть связано с историческими причинами.

Хотя в текущих реализациях Android Activity и Service getApplication() и getApplicationContext() возвращают один и тот же объект, нет никаких гарантий, что этовсегда будет иметь место (например, в реализации конкретного поставщика).

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

Почему getApplicationContext() существует в первую очередь?

getApplication()доступно только в классе Activity и классе Service, тогда как getApplicationContext() объявлено в классе Context.

Это фактически означает одно: при написании кода в широковещательном приемнике, который не является контекстом, а являетсяучитывая контекст в его методе onReceive, вы можете вызвать только getApplicationContext().Это также означает, что вам не гарантирован доступ к вашему приложению в BroadcastReceiver.

Когда вы смотрите на код Android, вы видите, что при подключении действие получает базовый контекст и приложение, иразные параметры.getApplicationContext() делегирует свой вызов baseContext.getApplicationContext().

Еще одна вещь: в документации сказано, что в большинстве случаев вам не нужно создавать подклассы. Приложение:

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

30 голосов
/ 16 февраля 2011

Сравнить getApplication() и getApplicationContext().

getApplication возвращает объект Application, который позволит вам управлять глобальным состоянием приложения и реагировать на некоторые ситуации устройства, такие как onLowMemory() и onConfigurationChanged().

getApplicationContext возвращает глобальный контекст приложения - отличие от других контекстов заключается в том, что, например, контекст активности может быть уничтожен (или иным образом недоступен) Android, когда ваша активность заканчивается. Контекст приложения остается доступным все время, пока существует объект приложения (который не привязан к определенному Activity), поэтому вы можете использовать его для таких вещей, как Уведомления , для которых требуется контекст, который будет доступен в течение более длительных периодов времени. и не зависит от переходных объектов пользовательского интерфейса.

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

29 голосов
/ 01 ноября 2012

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

Контекст - это общая абстракция, которая поддерживает насмешки и проксирование. Поскольку многие контексты привязаны к объекту с ограниченным сроком службы, например Activity, необходим способ получения более долгоживущего контекста для таких целей, как регистрация для будущих уведомлений. Это достигается с помощью Context.getApplicationContext(). Логическая реализация должна возвращать глобальный объект Application, но ничто не мешает реализации контекста возвращать оболочку или прокси с подходящим временем жизни.

Действия и услуги более конкретно связаны с объектом Application. Я полагаю, что полезность этого заключается в том, что вы можете создать и зарегистрировать в манифесте собственный класс, производный от Application, и быть уверенным, что Activity.getApplication() или Service.getApplication() вернуть конкретный объект этого определенного типа, который вы можете привести к производному классу Application и использовать для любых пользовательских целей.

Другими словами, getApplication() гарантированно возвращает объект Application, в то время как getApplicationContext() может вместо этого возвращать прокси.

0 голосов
/ 04 мая 2011

Чтобы ответить на вопрос, getApplication () возвращает объект Application, а getApplicationContext () возвращает объект Context. Основываясь на ваших собственных наблюдениях, я бы предположил, что оба контекста идентичны (то есть за кулисами класс Application вызывает последнюю функцию для заполнения части контекста базового класса или происходит какое-то эквивалентное действие). На самом деле не должно иметь значения, какую функцию вы вызываете, если вам просто нужен контекст.

...