Что такое 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
. Некоторые вещи, которые вы попытаетесь сделать с этим контекстом, потерпят неудачу, в основном связанные с графическим интерфейсом. - Могут появляться утечки памяти, если контекст из
getApplicationContext()
удерживается на каком-то объекте, который вы не очищаете впоследствии. Если же где-то удерживается контекстActivity
, то как толькоActivity
уничтожается сборщиком мусора, всё остальное тоже уничтожается. ОбъектApplication
остается на всю жизнь вашего процесса.
Правило большого пальца
В большинстве случаев используйте контекст, доступный непосредственно из компонента, в котором вы работаете в данный момент. Вы можете безопасно хранить ссылку на него, если она не выходит за пределы жизненного цикла этого компонента. Как только вам нужно сохранить ссылку на контекст в объекте, который живет за пределами вашей Activity
или другого компонента, даже временно, используйте ссылку на контекст приложения.