- Context
- ContextCompat
- Context в Android приложении
- Что такое Context?
- Контекст приложения
- Контекст Activity
- getContext() в ContentProvider
- Когда нельзя использовать getApplicationContext()?
- Правило большого пальца
- Статический способ получить «контекст» в Android?
- 20 ответов
- Статический способ получить «Контекст» в Android?
Context
Context – это объект, который предоставляет доступ к базовым функциям приложения: доступ к ресурсам, к файловой системе, вызов активности и т.д. Activity является подклассом Context, поэтому в коде мы можем использовать её как ИмяАктивности.this (напр. MainActivity.this), или укороченную запись this. Классы Service, Application и др. также работают с контекстом.
Доступ к контексту можно получить разными способами. Существуют такие методы как getApplicationContext(), getContext(), getBaseContext() или this, который упоминался выше, если используется в активности.
На первых порах не обязательно понимать, зачем он нужен. Достаточно помнить о методах, которые позволяют получить контекст и использовать их в случае необходимости, когда какой-нибудь метод или конструктор будет требовать объект Context в своих параметрах.
В свою очередь Context имеет свои методы, позволяющие получать доступ к ресурсам и другим объектам.
- getAssets()
- getResources()
- getPackageManager()
- getString()
- getSharedPrefsFile()
Возьмём к примеру метод getAssets(). Ваше приложение может иметь ресурсы в папке assets вашего проекта. Чтобы получить доступ к данным ресурсам, приложение использует механизм контекста, который и отвечает доступность ресурсов для тех, кто запрашивает доступ — активность, служба и т.д. Аналогично происходит с методом getResources. Например, чтобы получить доступ к ресурсу цвета используется конструкция getResources().getColor(), которая может получить доступ к данным из файла res/colors.xml.
Таким образом, создавая, например, вторую активность, мы можем сразу обеспечить ей доступ к своим ресурсам, так как активность относится к контексту. При создании собственных компонентов View также используется контекст в конструкторах, так как компонент тоже может использовать ваши ресурсы. При создании собственных классов, если вам нужно будет обращаться к контексту, то необходимо создать конструктор:
Через контекст можно узнать практически всю информацию о вашем приложении — имя пакета, класса и т.п.
Тем не менее, следует различать контекст в разных ситуациях. Допустим, у вас есть приложение с несколькими активностями. В манифесте можно прописать используемую тему как для всего приложения, так и для каждой активности в отдельности. Соответственно, выбор контекста повлияет на результат. Как правило, при использовании собственной темы предпочтительнее использовать контекст активности, а не приложения.
Очень часто начинающие программисты впадают в ступор, когда ключевое слово this не работает в анонимных классах, например, при щелчке кнопки. В этом случае, используйте полное имя класса перед ним.
При создании адаптеров для списков также обращаются к контексту.
Или ещё пример для адаптера в фрагменте ListFragment:
Здесь тоже следует быть внимательным, если используется своя тема для списка.
Последнее замечание относится к опытным программистам. Неправильный контекст может послужить источником утечки памяти. Если вы создадите собственный класс, в котором содержится статическая переменная, обращающая к контексту активности, то система будет держать ссылку на переменную. Если активность будет закрыта, то сборщик мусора не сможет очистить память от переменной и самой неиспользуемой активности. В таких случаях лучше использовать контекст приложения через метод getApplicationContext().
ContextCompat
В библиотеки совместимости появился свой класс для контекста ContextCompat. Он может вам пригодиться, когда студия вдруг подчеркнёт метод в старом проекте и объявит его устаревшим.
Допустим, мы хотим поменять цвет текста на кнопки.
Студия ругается, что нужно использовать новый вариант getColor(int, Theme). Заменим строчку.
Если посмотреть на исходники этого варианта, то увидим, что там тоже идёт вызов нового метода. Поэтому можно сразу использовать правильный вариант, если вы пишете под Marshmallow и выше.
Источник
Context в Android приложении
Что такое Context?
Как следует из названия, это контекст текущего состояния приложения или объекта. Это позволяет вновь созданным объектам понять, что вообще происходит. Обычно его вызывают, чтобы получить информацию о другой части программы.
Кроме того, Context является проводником в систему, он может предоставлять ресурсы, получать доступ к базам данных, преференсам и т.д. Ещё в Android приложениях есть Activity . Это похоже на проводник в среду, в которой выполняется ваше приложение. Объект Activity наследует объект Context . Он позволяет получить доступ к конкретным ресурсам и информации о среде приложения.
Context присутствует практически повсюду в Android приложении и является самой важной его частью, поэтому необходимо понимать, как правильно его использовать.
Неправильное использование Context может легко привести к утечкам памяти в Android приложении.
Существует много разных типов контекста, поэтому давайте разберёмся, что каждый из них представляет из себя, как и когда их правильно использовать.
Контекст приложения
Это singleton-экземпляр (единственный на всё приложение), и к нему можно получить доступ через функцию getApplicationContext() . Этот контекст привязан к жизненному циклу приложения. Контекст приложения может использоваться там, где вам нужен контекст, жизненный цикл которого не связан с текущим контекстом или когда вам нужно передать контекст за пределы Activity .
Например, если вам нужно создать singleton-объект для вашего приложения, и этому объекту нужен какой-нибудь контекст, всегда используйте контекст приложения.
Если вы передадите контекст Activity в этом случае, это приведет к утечке памяти, так как singleton-объект сохранит ссылку на Activity и она не будет уничтожена сборщиком мусора, когда это потребуется.
В случае, когда вам нужно инициализировать какую-либо библиотеку в Activity , всегда передавайте контекст приложения, а не контекст Activity .
Таким образом, getApplicationContext() нужно использовать тогда, когда известно, что вам нужен контекст для чего-то, что может жить дольше, чем любой другой контекст, который есть в вашем распоряжении.
Контекст Activity
Этот контекст доступен в Activity и привязан к её жизненному циклу. Контекст Activity следует использовать, когда вы передаете контекст в рамках Activity или вам нужен контекст, жизненный цикл которого привязан к текущему контексту.
getContext() в ContentProvider
Этот контекст является контекстом приложения и может использоваться аналогично контексту приложения. К нему можно получить доступ через метод getContext() .
Когда нельзя использовать getApplicationContext()?
Правило большого пальца
В большинстве случаев используйте контекст, доступный непосредственно из компонента, в котором вы работаете в данный момент. Вы можете безопасно хранить ссылку на него, если она не выходит за пределы жизненного цикла этого компонента. Как только вам нужно сохранить ссылку на контекст в объекте, который живет за пределами вашей Activity или другого компонента, даже временно, используйте ссылку на контекст приложения.
Источник
Статический способ получить «контекст» в Android?
есть ли способ получить текущий Context экземпляр внутри статического метода?
Я ищу этот путь, потому что я ненавижу сохранять экземпляр «контекста» каждый раз, когда он меняется.
20 ответов
в файле манифеста Android, заявляю следующее.
затем напишите класс:
Теперь везде звоните MyApplication.getAppContext() чтобы получить контекст приложения статически.
большинство приложений, которые хотят удобный метод, чтобы получить контекст приложения создать свой собственный класс, который расширяет android.app.Application .
руководство
вы можете сделать это, сначала создав класс в своем проекте следующим образом:
затем в вашем AndroidManifest вы должны указать имя своего класса в AndroidManifest.тег XML-это:
затем вы можете получить контекст приложения в любом статическом методе, используя следующее:
предупреждение
прежде чем добавлять что-то вроде вышеизложенного в свой проект, вы должны рассмотреть, что говорится в документации:
обычно нет необходимости в применении подкласс. В большинстве ситуаций, статические singletons могут обеспечить такую же функциональность в более модульном путь. Если ваш синглтон нуждается в глобальном контексте (например, для регистрации широковещательные приемники), функция, чтобы получить его можно дать Контекст, который внутренне использует контекст.getApplicationContext (), когда сначала построим синглтон.
отражение
существует также другой способ получить контекст приложения с помощью отражения. Отражение часто рассматривается в Android, и я лично думаю, что это не должно использоваться в производстве.
чтобы получить контекст приложения, мы должен вызывать метод для скрытого класса (ActivityThread), который был доступен с API 1:
есть еще один скрытый класс (AppGlobals), который предоставляет способ получить контекст приложения статически. Он получает контекст, используя ActivityThread таким образом, действительно нет никакой разницы между следующим методом и тем, который размещен выше:
удачи в кодировании!
Нет, я не думаю, что есть. К сожалению, вы застряли вызова getApplicationContext() с Activity или один из других подклассов Context . Кроме того,этой вопрос несколько связанных.
здесь без документов способ получить приложение (контекстно) из любого места в потоке пользовательского интерфейса. Он полагается на скрытый статический метод ActivityThread.currentApplication() . Он должен работать по крайней мере на Android 4.x.
обратите внимание, что этот метод может возвращать null, например, когда вы вызываете метод вне потока пользовательского интерфейса или приложение не привязано к потоку.
еще лучше использовать @RohitGhatol’ы решение, если вы можете изменить код приложения.
предполагая, что мы говорим о получении контекста приложения, я реализовал его, как предложил @Rohit Ghatol extending Application. Что произошло потом, так это то, что нет никакой гарантии, что контекст, полученный таким образом, всегда будет ненулевым. В то время, когда вам это нужно, это обычно потому, что вы хотите инициализировать помощника или получить ресурс, который вы не можете отложить во времени; обработка нулевого случая не поможет вам. Поэтому я понял, что в основном борюсь против Андроида архитектура, как указано в docs
Примечание: обычно нет необходимости в применении подкласс. В большинстве ситуаций статические синглеты могут обеспечивать ту же функциональность более модульным способом. Если ваш синглтон нуждается в глобальном контексте (например, для регистрации широковещательных приемников), включите контекст.getApplicationContext() в качестве аргумента контекста при вызове метода getInstance () вашего синглтона.
Она также предлагает решение этого проблема:
Если вы хотите какое-то глобальное состояние, которое может быть общим для разных частей вашего приложения, используйте синглтон. [. ] И это более естественно приводит к тому, как вы должны управлять этими вещами-инициализировать их по требованию.
Итак, я избавился от расширения приложения и передал контекст непосредственно getInstance () одноэлементного помощника, сохранив ссылку на контекст приложения в частном конструктор:
вызывающий передаст локальный контекст помощнику:
Итак, чтобы ответить на этот вопрос правильно: есть способы доступа к контексту приложения статически, но все они должны быть обескуражены, и вы должны предпочесть передачу локального контекста в getInstance () синглтона.
для тех, кто заинтересован, вы можете прочитать более подробную версию на блог fwd
это зависит от того, для чего вы используете контекст. Я могу придумать по крайней мере один недостаток этого метода:
если вы пытаетесь создать AlertDialog с AlertDialog.Builder на Application контекст не будет работать. Я считаю, что нужен контекст Activity .
Если вы открыты для использования RoboGuice, вы можете ввести контекст в любой класс, который вы хотите. Вот небольшой пример того, как это сделать с RoboGuice 2.0 (beta 4 на момент написания этой статьи)
я использовал это в какой-то момент:
это допустимый контекст, который я использовал при получении системных служб и работал.
но я использовал его только в модификациях framework / base и не пробовал его в приложениях Android.
на предупреждение что вы должны знать: при регистрации для широковещательных приемников с этим контекстом он не будет работать, и вы получите:
java.ленг.SecurityException: данный пакет вызывающего абонента android не выполняется в процессе ProcessRecord
Я думаю, вам нужно тело для getAppContext() способ:
Источник
Статический способ получить «Контекст» в Android?
Есть ли способ получить текущий Context экземпляр внутри статического метода?
Я ищу этот путь, потому что ненавижу сохранять экземпляр Context каждый раз, когда он меняется.
В файле манифеста Android объявите следующее.
Затем напишите класс:
Теперь везде звоните, MyApplication.getAppContext() чтобы получить статически контекст вашего приложения.
Большинство приложений, которым нужен удобный метод для получения контекста приложения, создают свой собственный класс, который расширяется android.app.Application .
РУКОВОДСТВО
Вы можете сделать это, сначала создав класс в своем проекте, как показано ниже:
Затем в вашем AndroidManifest вы должны указать имя вашего класса в теге AndroidManifest.xml:
Затем вы можете получить контекст приложения любым статическим методом, используя следующее:
ПРЕДУПРЕЖДЕНИЕ
Прежде чем добавить что-то подобное в ваш проект, вы должны рассмотреть, что написано в документации:
Обычно нет необходимости создавать подкласс Application. В большинстве случаев статические синглтоны могут предоставлять ту же функциональность более модульным способом. Если вашему синглтону нужен глобальный контекст (например, для регистрации широковещательных приемников), функции для его получения может быть задан контекст, который внутренне использует Context.getApplicationContext () при первом создании синглтона.
ОТРАЖЕНИЕ
Существует также другой способ получить контекст приложения, используя отражение. Отражение часто воспринимается в Android свысока, и я лично считаю, что его нельзя использовать в производстве.
Чтобы получить контекст приложения, мы должны вызвать метод для скрытого класса ( ActivityThread ), который был доступен с API 1:
Существует еще один скрытый класс ( AppGlobals ), который обеспечивает способ получения контекста приложения статическим способом. Он получает контекст с использованием, ActivityThread так что на самом деле нет разницы между следующим методом и тем, что опубликован выше:
Предполагая, что мы говорим о получении контекста приложения, я реализовал его в соответствии с предложением @Rohit Ghatol, расширяющего приложение. Что случилось потом, так это то, что нет никакой гарантии, что контекст, полученный таким образом, всегда будет ненулевым. В то время, когда вам это нужно, обычно потому, что вы хотите инициализировать помощника или получить ресурс, который вы не можете отложить во времени; обработка нулевого случая не поможет вам. Таким образом, я понял, что в основном борюсь с архитектурой Android, как указано в документации
Примечание. Обычно нет необходимости создавать подкласс Application. В большинстве ситуаций статические синглтоны могут предоставлять ту же функциональность более модульным способом. Если вашему синглтону нужен глобальный контекст (например, для регистрации широковещательных приемников), включите Context.getApplicationContext () в качестве аргумента Context при вызове метода getInstance () вашего синглтона.
Единственная причина, по которой Application существует как нечто, из которого вы можете извлечь информацию, заключается в том, что во время разработки до версии 1.0 один из наших разработчиков приложений постоянно задавал мне вопрос о необходимости иметь объект приложения верхнего уровня, из которого они могли бы извлекать, чтобы они могли иметь более «нормальный» «им модель приложения, и я в конце концов сдался. Я всегда буду сожалеть о том, что уступил в этом. 🙂
Она также предлагает решение этой проблемы:
Если вам нужно глобальное состояние, которое можно использовать в разных частях вашего приложения, используйте одиночный код. [. ] И это более естественно приводит к тому, как вы должны управлять этими вещами — инициализировать их по требованию.
Итак, я избавился от расширения Application и передал контекст напрямую в getInstance () хелпера singleton, сохранив ссылку на контекст приложения в приватном конструкторе:
вызывающий затем передаст локальный контекст помощнику:
Таким образом, чтобы правильно ответить на этот вопрос: существуют способы статического доступа к контексту приложения, но все они не должны поощряться, и вы должны предпочесть передачу локального контекста в getInstance () синглтона.
Для тех, кто заинтересован, вы можете прочитать более подробную версию в блоге FWD
Источник