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 и выше.
Источник
Полный список
— разбираемся в коде урока 21
— теория по Intent и Intent Filter
— немного о Context
На прошлом уроке (№ 21) мы создали приложение, которое содержит два Activity. Напомню, что для создания Activity, необходимо:
— создать класс, с суперклассом android.app.Activity
— создать Activity-запись в манифесте и указать ей созданный класс в поле Name
Надеюсь прошлый урок не вызвал особых трудностей и процедура создания Activity примерно уложилась в голове. Теперь мы можем обратить внимание на код вызова Activity.
Мы использовали объект Intent. О нем можно почитать здесь, здесь и здесь. Правда инфа достаточно сложна для понимания с нуля. Я попробую своими словами объяснить.
Что такое Intent
В нашем случае Intent – это объект, в котором мы прописываем, какое Activity нам необходимо вызвать. После чего мы передаем этот Intent-объект методу startActivity, который находит соответствующее Activity и показывает его. При создании Intent мы использовали конструктор Intent (Context packageContext, Class cls) с двумя параметрами.
Первый параметр – это Context. Если помните, когда мы программно создавали View в одном из прошлых уроков, мы тоже использовали в конструкторах объект Context. Activity является подклассом Context, поэтому мы можем использовать ее – this. Вкратце, Context – это объект, который предоставляет доступ к базовым функциям приложения таким как: доступ к ресурсам, к файловой системе, вызов Activiy и т.д. Я думаю, в дальнейшем мы рассмотрим примеры, где явно увидим, зачем Context передается и как используется.
Второй параметр – имя класса. Напомню, что при создании записи Activity в манифест-файле мы указываем имя класса. И теперь если мы укажем тот же класс в Intent – то система, просмотрев манифест-файл обнаружит соответствие и покажет соответствующий Activity.
В этом можно легко убедиться. Мы удалим запись об Activity из манифест-файла и попробуем его после этого вызвать. Откройте проект из прошлого урока P0211_TwoActivity, откройте манифест-файл, вкладка Application и удалите запись об ActivityTwo с помощью кнопки Remove. Сохраните все, запустите приложение и попробуйте вызвать Activity кнопкой “Go to Activity Two”. Приложение выдаст ошибку. Если посмотреть логи, то видим следующий текст:
ERROR/AndroidRuntime(367): android.content.ActivityNotFoundException: Unable to find explicit activity class
(Логи — вкладка LogCat в Eclipse. Если не видно такой, то идем в меню Window -> Show View -> Other, папка Android -> LogCat )
Система говорит нам, что не нашла такого Activity класса и любезно подсказывает, что, возможно, он не прописан в манифест-файле. Снова пропишите Activity в манифест-файле, все сохраните и запускайте. Теперь должно работать.
Явный вызов
Вызов Activity с помощью такого Intent – это явный вызов. Т.е. с помощью класса мы явно указываем какое Activity хотели бы увидеть. Это обычно используется внутри одного приложения. Схематично это можно изобразить так:
Здесь мы создаем Intent, в качестве параметра передаем ему класс Class_B. Далее вызываем метод startActivity с созданным Intent в качестве параметра. Метод проверяет AndroidManifest на наличие Activity связанной с классом Class_B и если находит, то отображает. Все это в пределах одного приложения.
Неявный вызов
Существует также неявный вызов Activity. Он отличается тем, что при создании Intent мы используем не класс, а заполняем параметры action, data, category определенными значениями. Комбинация этих значений определяют цель, которую мы хотим достичь. Например: отправка письма, открытие гиперссылки, редактирование текста, просмотр картинки, звонок по определенному номеру и т.д. В свою очередь для Activity мы прописываем Intent Filter — это набор тех же параметров: action, data, category (но значения уже свои — зависят от того, что умеет делать Activity). И если параметры нашего Intent совпадают с условиями этого фильтра, то Activity вызывается. Но при этом поиск уже идет по всем Activity всех приложений в системе. Если находится несколько, то система предоставляет вам выбор, какой именно программой вы хотите воспользоваться. Схематично это можно изобразить так:
В Application_1 создается Intent, заполняются параметры action, data, category. Для удобства, получившийся набор параметров назовем Param_C. С помощью startActivity этот Intent отправляется на поиски подходящей Activity, которая сможет выполнить то, что нам нужно (т.е. то, что определено с помощью Param_C). В системе есть разные приложения, и в каждом из них несколько Activity. Для некоторых Activity определен Intent Filter (наборы Param_A, Param_B и т.д.), для некоторых нет. Метод startActivity сверяет набор параметров Intent и наборы параметров Intent Filter для каждой Activity. Если наборы совпадают (Param_C для обоих), то Activity считается подходящей.
Если в итоге нашлась только одна Activity – она и отображается. Если же нашлось несколько подходящих Activity, то пользователю выводится список, где он может сам выбрать какое приложение ему использовать.
Например, если в системе установлено несколько музыкальных плееров, и вы запускаете mp3, то система выведет вам список Activity, которые умеют играть музыку и попросит выбрать, какое из них использовать. А те Activity, которые умеют редактить текст, показывать картинки, звонить и т.п. будут проигнорированы.
Если для Activity не задан Intent Filter (Activity_24 на схеме), то Intent с параметрами ему никак не подойдет, и оно тоже будет проигнорировано.
Если проводить аналогии — можно сравнить Intent с ключом, а Intent Filter с замкОм, за которым сидит прекрасное Activity )))
Мы будем постепенно узнавать нюансы этого механизма и значения которыми заполняются параметры action, data и category в Intent и Intent Filter. Сейчас важно понять, что в случае неявного вызова одно приложение посылает Intent, а все другие сверяют его параметры со своими Activity -> Intent Filter. Intent – это базовое понятие системы Android и без него нам никуда. Оно применяется не только для Activity. Но об этом позднее.
Ну вот, хотел написать пару вводных слов, а получилось достаточно подробное объяснение со схемами и примерами ) Надеюсь, что у меня получилось донести смысл технологии Intent-ов. В дальнейшем будем практиковаться и закрепим тему.
На следующем уроке:
— Activity LifeCycle – поведение Activity при создании, вызове, закрытии
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Context — контекст в android — что это, как получить и зачем использовать
Контекст (Context) – это базовый абстрактный класс, реализация которого обеспечивается системой Android. Этот класс имеет методы для доступа к специфичным для конкретного приложения ресурсам и классам и служит для выполнения операций на уровне приложения, таких, как запуск активностей, отправка широковещательных сообщений, получение намерений и прочее. От класса Context наследуются такие крупные и важные классы, как Application, Activity и Service, поэтому все его методы доступны из этих классов.
Получить контекст внутри кода можно одним из следующих методов:
- getBaseContext(получить ссылку на базовый контекст)
- getApplicationContext(получить ссылку на объект приложения)
- getContext (внутри активности или сервиса получить ссылку на этот объект)
- this(то же, что и getContext)
- MainActivity.this (внутри вложенного класса или метода получить ссылку на объект MainActivity)
- getActivity(внутри фрагмента получить ссылку на объект родительской активности)
Контекст (Context) – это базовый абстрактный класс, реализация которого обеспечивается системой Android. Этот класс имеет методы для доступа к специфичным для конкретного приложения ресурсам и классам и служит для выполнения операций на уровне приложения, таких, как запуск активностей, отправка широковещательных сообщений, получение намерений и прочее. От класса Context наследуются такие крупные и важные классы, как Application, Activity и Service, поэтому все его методы доступны из этих классов. Источник
Получить контекст внутри кода можно одним из следующих методов:
- getBaseContext(получить ссылку на базовый контекст)
- getApplicationContext(получить ссылку на объект приложения)
- и(внутри активности или сервиса получить ссылку на этот объект)
- this(то же, что и getContext)
- MainActivity.this (внутри вложенного класса или метода получить ссылку на объект MainActivity)
- getActivity(внутри фрагмента получить ссылку на объект родительской активности)
Сообщение умрёт вместе с приложением:
Toast.makeText(getApplicationContext(), «Text «, Toast.LENGTH_SHORT).show();
Будет видно даже после завершения приложения:
Toast.makeText(getBaseContext(), «Text «, Toast.LENGTH_SHORT).show();
Здравствуйте! В статье ошибка, в списке методов получения контекста вместо getContext — и
Большое спасибо за уроки!
Добрый день. Я наверное не совсем до конца понимаю, но при использовании Toast.makeText(this, «Text», Toast.LENGTH_SHORT).show(); сообщение не умирает вместе в активностью. Я в onCreate поместил вот такой код:
Toast.makeText(this, «This is toast», Toast.LENGTH_LONG).show();
finish();
и при запуске активити сразу же умирает, а Toast остается видным. Объясните что я делаю не так?
Метод finish() завершает активити, а не тост.
Для отправки комментария вам необходимо авторизоваться.
Источник