В различных частях кода Android я видел:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
Однако я не могу найти какое-либо достойное объяснение того, что является предпочтительным, и при каких обстоятельствах, которые должны быть использованы.
Будем весьма благодарны за указатели на документацию по этому вопросу и рекомендации о том, что может сломаться при выборе неправильного.
android
android-context
Альнитак
источник
источник
Ответы:
Я согласен, что документация скудна, когда дело доходит до контекстов в Android, но вы можете собрать воедино несколько фактов из различных источников.
Этот пост в официальном блоге разработчиков Google Android был написан в основном для устранения утечек памяти, но также содержит некоторую полезную информацию о контекстах:
Чтение статьи чуть дальше расскажет о разнице между ними и о том, когда вы можете рассмотреть возможность использования Context приложения (
Activity.getApplicationContext()
) вместо использования контекста Activitythis
). В основном контекст приложения связан с приложением и всегда будет одинаковым на протяжении жизненного цикла вашего приложения, где контекст действия связан с действием и может быть уничтожен много раз, так как действие разрушается во время изменения ориентации экрана и например.Я не мог найти ничего о том, когда использовать getBaseContext (), кроме сообщения от Dianne Hackborn, одного из инженеров Google, работающих над Android SDK:
Это было из сообщения в новостной группе android-разработчиков , вы можете подумать и о том, чтобы задать свой вопрос там, потому что горстка людей, работающих над Android, фактически следят за этой группой новостей и отвечают на вопросы.
Поэтому в целом представляется предпочтительным использовать глобальный контекст приложения, когда это возможно.
источник
Don't use getBaseContext()
. Может ли кто-нибудь уточнить это?Вот что я нашел относительно использования
context
:1) Внутри
Activity
себя, используйтеthis
для раздувания макетов и меню, зарегистрируйте контекстные меню, создайте экземпляры виджетов, запустите другие действия, создайте новоеIntent
внутри , создайтеActivity
экземпляры предпочтений или другие методы, доступные вActivity
.Раздувать макет:
Раздувать меню:
Зарегистрировать контекстное меню:
Создание виджета:
Начать
Activity
:Определить предпочтения:
2) Для класса всего приложения используйте,
getApplicationContext()
поскольку этот контекст существует для продолжительности жизни приложения.Получить имя текущего пакета Android:
Привязать класс приложения:
3) Для прослушивателей и других типов классов Android (например, ContentObserver) используйте подстановку контекста, например:
где
this
илиcontext
является контекстом класса (Activity и т. д.).Activity
замена контекста:Замена контекста слушателя:
ContentObserver
замена контекста:4) Для
BroadcastReceiver
(включая встроенный / встроенный получатель) используйте собственный контекст получателя.Внешний
BroadcastReceiver
:Встроенный / Встроенный
BroadcastReceiver
:5) Для Сервисов используйте собственный контекст сервиса.
6) Для тостов обычно используют
getApplicationContext()
, но, где возможно, используют контекст, переданный из Activity, Service и т. Д.Используйте контекст приложения:
Использовать контекст, переданный из источника:
И последнее, не используйте
getBaseContext()
в соответствии с рекомендациями разработчиков платформы Android.ОБНОВЛЕНИЕ: Добавьте примеры
Context
использования.источник
OuterClass.this
; см. комментарии в stackoverflow.com/questions/9605459/…Я прочитал эту ветку несколько дней назад, задавая себе тот же вопрос. Мое решение после прочтения было простым: всегда используйте applicationContext.
Однако, я столкнулся с проблемой, я потратил несколько часов, чтобы найти ее, и несколько секунд, чтобы ее решить ... (меняя одно слово ...)
Я использую LayoutInflater, чтобы надуть представление, содержащее Spinner.
Итак, вот две возможности:
1)
2)
Затем я делаю что-то вроде этого:
Что я заметил: если вы создали свой экземпляр linearLayout с помощью applicationContext, то при нажатии на счетчик в вашей активности вы получите неперехваченное исключение, исходящее от виртуальной машины dalvik (а не из вашего кода, поэтому я потратил много времени найти где была моя ошибка ...).
Если вы используете baseContext, то все в порядке, откроется контекстное меню, и вы сможете выбрать один из вариантов.
Итак, вот мой вывод: я полагаю (я не проверял это дальше), чем baseContext требуется при работе с contextMenu в вашей деятельности ...
Тест был выполнен с использованием API 8 и протестирован на HTC Desire, Android 2.3.3.
Я надеюсь, что мой комментарий не скучал до сих пор, и желаю вам всего наилучшего. Удачного кодирования ;-)
источник
Во-первых, я согласен, что мы должны использовать appcontext, когда это возможно. тогда «это» в деятельности. У меня никогда не было необходимости в базовом контексте.
В моих тестах в большинстве случаев их можно поменять местами. В большинстве случаев причина, по которой вы хотите получить контекст, заключается в доступе к файлам, настройкам, базе данных и т. Д. Эти данные в конечном итоге отражаются в виде файлов в папке личных данных вашего приложения (/ data / data /). Независимо от того, какой контекст вы используете, они будут сопоставлены с одной и той же папкой / файлами, так что вы в порядке.
Это то, что я заметил. Может быть, есть случаи, вы должны их различать.
источник
В некоторых случаях вы можете использовать контекст Activity поверх контекста приложения при запуске чего-либо в потоке. Когда поток завершает выполнение, и вам нужно вернуть результат обратно в действие вызывающего, вам нужен этот контекст с обработчиком.
источник
Простыми словами
getApplicationContext()
Как подсказывает название метода, ваше приложение узнает подробности приложения, к которым вы можете получить доступ из любой точки приложения. Таким образом, вы можете использовать это в привязке сервисов, регистрации трансляций и т. Д., ПокаApplication context
приложение не закроется.getActivity()
илиthis
сделает ваше приложение осведомленным о текущем экране, который также виден, и сведения об уровне приложения, предоставленныеapplication context
. Так что все, что вы хотите знать о текущем экране, какWindow
ActionBar
Fragementmanger
и так, доступно в этом контексте. В основном так иActivity
расширяетсяContext
. Этот контекст будет активен до тех пор, пока текущий компонент (активность) не будет активенисточник
Что такое контекст? Мне лично нравится думать о контексте как о состоянии вашего приложения в любой момент времени. Контекст приложения представляет собой глобальную или базовую конфигурацию вашего приложения, на которую может опираться действие или служба, и представляет экземпляр конфигурации вашего приложения или переходное состояние для него.
Если вы посмотрите на источник для android.content.Context, вы увидите, что Context является абстрактным классом, и комментарии к классу следующие:
Интерфейс для глобальной информации о среде приложения. Это абстрактный класс, реализация которого обеспечивается системой Android. Он позволяет получить доступ к
application-specific
ресурсам и классам, а также к дополнительным вызовам дляapplication-level
таких операций, как запуск, широковещание и получение и т. Д. От этого я отказываюсь от того, что Context предоставляет общую реализацию для доступа к уровню приложения, а также к уровню системы. Ресурсы. Ресурсы уровня приложения могут иметь доступ к таким вещам, как ресурсы[getResources()]
или активы String, а ресурсы[getAssets()]
уровня системы - это все, к чему вы обращаетесьContext.getSystemService().
На самом деле, посмотрите на комментарии к методам, и они, кажется, усиливают это понятие:
getSystemService()
: Вернуть дескриптор вsystem-level
сервис по имени. Класс возвращаемого объекта зависит от запрошенного имени.getResources()
Возвращает экземпляр ресурсов для пакета вашего приложения.getAssets()
Возвращает экземпляр ресурсов для пакета вашего приложения. Возможно, стоит отметить, что в абстрактном классе Context все вышеперечисленные методы являются абстрактными! Только один экземпляр getSystemService (Class) имеет реализацию, которая вызывает абстрактный метод. Это означает, что реализация для них должна обеспечиваться в основном реализующими классами, которые включают в себя:Глядя на документацию API, иерархия классов выглядит следующим образом:
контекст
| - ContextWrapper
| - - Применение
| - - ContextThemeWrapper
| - - - - Деятельность
| - - Обслуживание
| - - - IntentService
Так как мы знаем, что
Context
само по себе не дает никакого понимания, мы спускаемся по дереву, смотрим наContextWrapper
и понимаем, что там тоже не так много. Поскольку приложение расширяетсяContextWrapper
, там тоже не на что смотреть, поскольку оно не отменяет реализацию, предоставляемуюContextWrapper
. Это означает, что реализация для Context предоставляется ОС и скрыта отAPI
. Вы можете взглянуть на конкретную реализацию для Context, посмотрев на источник для класса ContextImpl.источник
Я использовал только это и
getBaseContext
при поджаривании изonClick
(очень зеленый нуб на Java и Android). Я использую это, когда мой кликер находится непосредственно в действии и должен использоватьсяgetBaseContext
в анонимном внутреннем кликере. Я предполагаю, что это в значительной степени хитростьgetBaseContext
, возможно, она возвращает контекст действия, в котором скрывается внутренний класс.источник
MyActivity.this
. Использование описанного вами базового контекста, вероятно, не вызовет проблем, но это неправильно.