Чем отличается activity Context от application Context?
Activity Context создается при создании активити и уничтожается вместе с активити. Контекст – тяжелый объект. Когда говорят об утечке памяти в андроиде, имеют в виду утечку контекста, т.е. ситуацию, когда контекст активити хранится после вызова Activity.onDestroy(). Не передавайте контекст активити в другой объект, если не известно как долго этот объект проживет. Подробнее о memory leak.
Application Context – синглтон. Application Context создается при создании объекта Application и живет, пока жив процесс приложения. По этой причине Application Context можно безопасно инжектить в другие синглтоны в приложении. Не рекомендуется использовать Application Context для старта активити, потому что необходимо создание новой задачи, и для layout inflation , потому что используется дефолтная тема.
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 также используется контекст в конструкторах, так как компонент тоже может использовать ваши ресурсы. При создании собственных классов, если вам нужно будет обращаться к контексту, то необходимо создать конструктор:
// В классе сделайте конструктор, куда будет передаваться контекст: public MyClass(Context context) < this.context = context; >// в активности MyClass cat = new MyClass(this);
Через контекст можно узнать практически всю информацию о вашем приложении — имя пакета, класса и т.п.
// имя вашего пакета String info = this.getApplicationInfo().packageName;
Тем не менее, следует различать контекст в разных ситуациях. Допустим, у вас есть приложение с несколькими активностями. В манифесте можно прописать используемую тему как для всего приложения, так и для каждой активности в отдельности. Соответственно, выбор контекста повлияет на результат. Как правило, при использовании собственной темы предпочтительнее использовать контекст активности, а не приложения.
Очень часто начинающие программисты впадают в ступор, когда ключевое слово this не работает в анонимных классах, например, при щелчке кнопки. В этом случае, используйте полное имя класса перед ним.
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < Toast.makeText(MainActivity.this, "Мяу", Toast.LENGTH_SHORT).show(); > >);
При создании адаптеров для списков также обращаются к контексту.
if (convertView == null) < convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false); >
Или ещё пример для адаптера в фрагменте ListFragment:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) < String[] names; // имена котов // бла-бла-бла, т.е. мяу-мяу-мяу ArrayAdapteradapter = new ArrayAdapter<>( inflater.getContext(), android.R.layout.simple_list_item_1, names); setListAdapter(adapter); return super.onCreateView(inflater, container, savedInstanceState); >
Здесь тоже следует быть внимательным, если используется своя тема для списка.
Последнее замечание относится к опытным программистам. Неправильный контекст может послужить источником утечки памяти. Если вы создадите собственный класс, в котором содержится статическая переменная, обращающая к контексту активности, то система будет держать ссылку на переменную. Если активность будет закрыта, то сборщик мусора не сможет очистить память от переменной и самой неиспользуемой активности. В таких случаях лучше использовать контекст приложения через метод getApplicationContext().
ContextCompat
В библиотеки совместимости появился свой класс для контекста ContextCompat. Он может вам пригодиться, когда студия вдруг подчеркнёт метод в старом проекте и объявит его устаревшим.
context.getResources().getColor(R.color.some_color_resource_id);
Допустим, мы хотим поменять цвет текста на кнопки.
public void onClick(View view) < int color = getResources().getColor(R.color.colorPrimary); // ругается Button button = (Button) findViewById(R.id.button); button.setTextColor(color); >
Студия ругается, что нужно использовать новый вариант getColor(int, Theme). Заменим строчку.
// Теперь не ругается int color = ContextCompat.getColor(this, R.color.colorPrimary);
Если посмотреть на исходники этого варианта, то увидим, что там тоже идёт вызов нового метода. Поэтому можно сразу использовать правильный вариант, если вы пишете под Marshmallow и выше.
// Только для API 23 и выше int color = getResources().getColor(R.color.colorPrimary, getTheme());
Context в Android приложении
Как следует из названия, это контекст текущего состояния приложения или объекта. Это позволяет вновь созданным объектам понять, что вообще происходит. Обычно его вызывают, чтобы получить информацию о другой части программы.
Кроме того, 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 или другого компонента, даже временно, используйте ссылку на контекст приложения.
- android development
- android
- андроид
- перевод с английского
- программирование
- разработка
- devcolibri
- никто не читает теги
- Разработка мобильных приложений
- Разработка под Android
Context – контекст в android – что это, как получить и зачем использовать
Контекст (Context) – это базовый абстрактный класс, реализация которого обеспечивается системой Android. Этот класс имеет методы для доступа к специфичным для конкретного приложения ресурсам и классам и служит для выполнения операций на уровне приложения, таких, как запуск активностей, отправка широковещательных сообщений, получение намерений и прочее. От класса Context наследуются такие крупные и важные классы, как Application, Activity и Service, поэтому все его методы доступны из этих классов.
Методы получения контекста и их различие
Получить контекст внутри кода можно одним из следующих методов:
- getBaseContext(получить ссылку на базовый контекст)
- getApplicationContext(получить ссылку на объект приложения)
- getContext (внутри активности или сервиса получить ссылку на этот объект)
- this(то же, что и getContext)
- MainActivity.this (внутри вложенного класса или метода получить ссылку на объект MainActivity)
- getActivity(внутри фрагмента получить ссылку на объект родительской активности)
Все эти способы дадут нам возможность получить ссылку на объект, содержащий методы класса Context.
Как было сказано выше, контекст является базовым классом для классов Application, Activity и Service, а значит его методы входят в их состав. Именно поэтому для передачи контекста в качестве параметра можно использовать как ссылку на сам контекст (getBaseContext), так и ссылки на наследуемые классы (getApplicationContext, getContext, this, MainActivity.this, getActivity).
Но тут важно понимать, что время жизни этих ссылок будет разное. Ссылка на переданный объект будет работать, пока будет жить этот объект. Поэтому в качестве контекста важно передать такую ссылку, которая будет рабочей на всём протяжении работы вызываемого метода.
Например, если вызвать сообщение с помощью Toast, используя разные context, то:
Сообщение умрёт вместе с активностью:
Toast.makeText(this, “Text”, Toast.LENGTH_SHORT).show();Сообщение умрёт вместе с приложением:
Toast.makeText(getApplicationContext(), “Text “, Toast.LENGTH_SHORT).show();Будет видно даже после завершения приложения:
Toast.makeText(getBaseContext(), “Text “, Toast.LENGTH_SHORT).show();
То есть, мы видим, что хотя контекст одинаков у разных объектов, сами эти объекты могут жить разное время.
Контекст можно представить, как набор функций для работы на уровне приложения, вошедший в состав таких крупных классов, как Application, разных видов Activity, Service.
Контекст (Context) – это базовый абстрактный класс, реализация которого обеспечивается системой Android. Этот класс имеет методы для доступа к специфичным для конкретного приложения ресурсам и классам и служит для выполнения операций на уровне приложения, таких, как запуск активностей, отправка широковещательных сообщений, получение намерений и прочее. От класса Context наследуются такие крупные и важные классы, как Application, Activity и Service, поэтому все его методы доступны из этих классов. Источник
Методы получения контекста и их различие
Получить контекст внутри кода можно одним из следующих методов:
- getBaseContext(получить ссылку на базовый контекст)
- getApplicationContext(получить ссылку на объект приложения)
- и(внутри активности или сервиса получить ссылку на этот объект)
- this(то же, что и getContext)
- MainActivity.this (внутри вложенного класса или метода получить ссылку на объект MainActivity)
- getActivity(внутри фрагмента получить ссылку на объект родительской активности)
Все эти способы дадут нам возможность получить ссылку на объект, содержащий методы класса Context.
Как было сказано выше, контекст является базовым классом для классов Application, Activity и Service, а значит его методы входят в их состав. Именно поэтому для передачи контекста в качестве параметра можно использовать как ссылку на сам контекст (getBaseContext), так и ссылки на наследуемые классы (getApplicationContext, getContext, this, MainActivity.this, getActivity).
Но тут важно понимать, что время жизни этих ссылок будет разное. Ссылка на переданный объект будет работать, пока будет жить этот объект. Поэтому в качестве контекста важно передать такую ссылку, которая будет рабочей на всём протяжении работы вызываемого метода.
Например, если вызвать сообщение с помощью Toast, используя разные context, то:
Сообщение умрёт вместе с активностью:
Toast.makeText(this, “Text”, Toast.LENGTH_SHORT).show();
Сообщение умрёт вместе с приложением:
Toast.makeText(getApplicationContext(), “Text “, Toast.LENGTH_SHORT).show();
Будет видно даже после завершения приложения:
Toast.makeText(getBaseContext(), “Text “, Toast.LENGTH_SHORT).show();
То есть, мы видим, что хотя контекст одинаков у разных объектов, сами эти объекты могут жить разное время.
Контекст можно представить, как набор функций для работы на уровне приложения, вошедший в состав таких крупных классов, как Application, разных видов Activity, Service.
Вам також може сподобатися

Создаем android-приложения 0 7 767
Продолжаем серию уроков по разработке android-приложений в Android Studio на языке Kotlin. Пришло время

Дизайн android приложений 1 5 230
В этом уроке рассказывается, как работать с экранами разного разрешения с помощью не зависящих

Инструменты android разработчика 2 13 695
Что такое Realm? Изучая хранение данных в БД по урокам на нашем канале, вы

Уроки по android разработке на Java 8 2 014
[:ru]Мы начинаем курс по разработке игры для android с помощью библиотеки libGDX. На нашем

Уроки по android разработке на Java 0 6 661
Начиная с версии Android 5.0 Lolipop предоставлено много различных способов облегчить навигацию внутри андроид-приложения, используя,

Документация по android 3 8 302
Перевод документации официального сайта developer.android.com RelativeLayout – это view group, которая располагает на экране
Коментарі: 5
Здравствуйте! В статье ошибка, в списке методов получения контекста вместо getContext – и
Большое спасибо за уроки!
admin (автор)
Спасибо, исправлено.
Добрый день. Я наверное не совсем до конца понимаю, но при использовании Toast.makeText(this, «Text», Toast.LENGTH_SHORT).show(); сообщение не умирает вместе в активностью. Я в onCreate поместил вот такой код:
Toast.makeText(this, “This is toast”, Toast.LENGTH_LONG).show();
finish();
и при запуске активити сразу же умирает, а Toast остается видным. Объясните что я делаю не так?
