Освоение контекста Android

1656605657 osvoenie konteksta android

от Гаурава

Контекст в Android является одним из наиболее используемых злоупотребляющих объектов. Но большинство статей в Интернете сосредоточено на определении того, что это такое. Я не мог найти хороший ресурс, который дал бы мне понимание и помог мне понять общую картину. Потому я попытался упростить ситуацию с помощью этой статьи.

xYtafNOmFZOHjNUTahCLSVsNkwPP7JSR1gxn
Какой контекст использовать? Авторство изображения: Pexels

Предисловие

Моя миссия этой статьи – помочь вам освоить контекст Android. Это одна из основных тем разработки Android и вряд ли любой разработчик использует контекст полностью и так, как он был разработан.

Сначала я опубликовал эту статью в качестве серии из четырех публикаций на своем веб-сайте. Если вам интересно читать раздел по разделу, не стесняйтесь читать там.

Начинаем

Вы когда-нибудь сталкивались с таким вопросом: в чем разница между getContext(), this, getBaseContext()и getApplicationContext()? Если да, то эта статья поможет прояснить большинство ваших недоразумений.

Примечание: вы должны знать основы разработки Android, таких как Activity, Fragments, Broadcast Receiver и другие строительные блоки. Если вы новый разработчик, который только начинает свой путь в мир Android, это может быть не самое лучшее место для начала.

Что такое контекст?

Давайте посмотрим в глаза, контекст является одной из наиболее плохо разработанных функций Android API. Это можно назвать объектом Бог.

Приложение для Android или набор пакетов приложений (APK) – это набор компонентов. Эти компоненты определены в манифесте и состоят в основном из Activity (UI), Service (Background), BroadcastReceiver (Action), ContentProvider (Data) и Resources (изображения, строки и т.п.).

Разработчик может предоставить эти компоненты системе с помощью фильтра намерений. Например, отправить электронную почту или поделиться фотографией. Они также могут предоставлять доступ к компонентам только другим компонентам программы.

Аналогично операционная система Android также была разработана для раскрытия компонентов. Некоторые хорошо известны – WifiManager, Vibrator и PackageManager.

Контекст – это мост между компонентами. Вы используете его для связи между компонентами, создания экземпляров и доступа к компонентам.

Ваши собственные компоненты

Мы используем контекст для создания экземпляров наших компонентов с помощью Activity, Content Provider, BroadcastReceiver и т.д. Мы также используем его для доступа к ресурсам и файловым системам.

Ваш компонент и компонент системы

Контекст выступает как точка входа в систему Android. Некоторые хорошо используемые компоненты системы – WifiManager, Vibrator и PackageManager. Вы можете получить доступ к WifiManager с помощью context.getSystemService(Context.WIFI_SERVICE).

Таким же образом вы можете использовать контекст для доступа к файловой системе, предназначенной для вашей программы как пользователя в ОС.

Ваш собственный компонент и компонент другого приложения

Связь между вашими собственными компонентами и другими компонентами программы почти идентична, если вы используете подход фильтрации намерений. В конце концов каждый компонент является равноправным гражданином в Android.

Ниже приведен пример намерения, используемого для отправки электронной почты. Все компоненты, предлагающие это действие, будут предоставлены пользователю, который сможет выбрать, что использовать.
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

Резюме

Согласимся, что у Android все является компонентом. Контекст – это мост между компонентами. Вы используете его для связи между компонентами, создания экземпляров и доступа к компонентам. Надеюсь, теперь определение понятно.

Различные типы контекста

Есть много способов удержать контекст (замечен плохой дизайн).

В большинстве случаев, когда нам нужен контекст, мы используем один из следующих:

- Application instance as context- Activity	- Instance of your activity (this)	- getApplicationContext() in Activity	- getBaseContext() in Activity- Fragment	- getContext() in Fragment- View	- getContext() in View- Broadcast Receiver	- Context received in broadcast receiver- Service	- Instance of your service (this)	- getApplicationContext() in Service- Context	- getApplicationContext() in Context instance

Я разделяю типы контекста на две категории: Контекст пользовательского интерфейса и Контекст без интерфейса. Это различие поможет вам понять n-ways получше.

Контекст пользовательского интерфейса

На самом деле только ContextThemeWrapper является контекстом пользовательского интерфейса, что означает Контекст + ваша тема.

Деятельность расширяется ContextThemeWrapper. Это причина того, что когда вы раздуваете любой XML, ваши взгляды тематические. Если вы расширите свой макет с помощью контекста без интерфейса, макет не будет тематическим. Давай, попробуй.

Если вы используете Activity в качестве заполнителя контекста, вы гарантированно используете контекст интерфейса пользователя. Если вы используете метод getContext из Fragment, вы косвенно используете Activity (если вы подключили Fragment через fragmentManager к активности).

Но view.getContext() не гарантируется, что это контекст пользовательского интерфейса.

Если View был создан с помощью Layout Inflater и передан контекст пользовательского интерфейса, вы получите контекст UI. Но если он был создан, не передавая пользовательский интерфейс, вы получите другой контекст обратно.

UI Context- Activity	- Instance of your activity (this)- Fragment	- getContext() in Fragment- View	- getContext() in View (if View was constructed using UI-Context)

Контекст без интерфейса

Все, кроме пользовательского интерфейса, не является контекстом интерфейса. Технически все, что не ContextThemeWrapper, является контекстом без интерфейса.

Разрешено делать контекст без пользовательского интерфейса почти все, что может сделать UI-Context (замечен плохой дизайн). Но, как мы уже отмечали выше, вы теряете тему.

Non-UI Context- Application instance as context- Activity	- getApplicationContext() in Activity- Broadcast Receiver	- Context received in broadcast receiver- Service	- Instance of your service (this)	- getApplicationContext() in Service- Context	- getApplicationContext() in Context instance

Совет: все типы контекстов должны быть кратковременными, кроме контекста программы. Это тот, который вы получаете от вашего класса программы или от использования getApplicationContext() метод, когда у вас есть доступ к контексту.

Резюме

Мы немного упростили это, поместив Context в два ведра. Контекст пользовательского интерфейса — это контекст + тематика, а технически любой класс, который является подклассом ContextThemeWrapper входит в это ведро. Контекст без интерфейса – это все другие типы контекста.

Где что использовать

Возникает вопрос: что пойдет не так, если использовать контекст не в том месте? Ниже приведены несколько сценариев:

Сценарий 1

Скажем, вы раздуваете макет и используете контекст без интерфейса. Что может пойти не так ли? Можно в этом случае догадаться: тематического макета не получится. Не так уж плохо, хм? Это терпимо.

Сценарий 2

Вы передаете UI-Context куда-нибудь, где ему нужен только доступ к ресурсам или доступ к файловой системе. Что не может не так ли? Краткий ответ: Ничего. Помните, UI-Context=Контекст+Тема. Он с удовольствием послужит вам контекстом.

Сценарий 3

Вы передаете UI-Context куда-нибудь, где ему нужен только доступ к ресурсам или доступ к файловой системе но это длительная операция в фоновом режиме. Скажем, загрузка файла. Что может пойти не так ли? Краткий ответ: утечка памяти.

Если вам повезет и загрузка завершается быстро, объект увольняется и все в порядке. Светит солнце и щебетают птицы. Это одна из самых распространенных ошибок разработчиков. Они передают ссылку UI-Context на долгоживущие объекты и иногда это не имеет побочных эффектов.

Однако иногда Android хочет требовать памяти для одного из требований вашего следующего компонента или требований другого компонента и оооооо!!! В вашем приложении не хватает памяти. Не волнуйся, я объясню.

Утечка памяти или сбой! Это оно.

Да, это самый плохой сценарий, когда вы используете контекст не в том месте. Если вы новичок в мире разработки приложений, позвольте мне поделиться мудростью. Истоки памяти обратно пропорциональны вашему опыту. Каждый разработчик Android имеет утечку памяти. В этом нет стыда.

Стыдно, когда ты повторяешь ошибку снова и разоблачаешь ее так же. Если вы каждый раз утечки памяти по-разному, поздравляем, вы растете. Я объяснил, что такое утечка памяти, с помощью короткой истории.

Ладно, я понял, но какое здесь отношение к контексту?

Скажите это вслух: «Замечен плохой дизайн».

Почти все в Android нуждается в доступе к Context. Наивные разработчики передают UI Context, потому что это то, к чему у них доступ очень легко. Они передают короткоживущий контекст (обычно контекст активности) долгоживущим объектам, и перед тем, как память/деньги возвращаются в систему, они сталкиваются с кризисом. Уххх!!!

Самый простой способ справиться с этим – асинхронная задача или широковещательный приемник. Но их обсуждение не входит в рамки настоящей статьи.

Резюме

  • Вам нужен доступ к информации, связанной с пользовательским интерфейсом? Используйте UI-Context. Раздувание просмотров и показ диалогов – это два варианта использования, которые я могу придумать.
  • В противном случае используйте контекст без пользовательского интерфейса.
  • Убедитесь, что вы не передаете короткоживущий контекст долгоживущим объектам.
  • Передавайте знания, помогайте людям, сажайте деревья и приглашайте меня на кофе.

Советы и подсказки

Какая разница между this, getApplicationContext() и getBaseContext()?

Это вопрос, с которым сталкивался каждый разработчик Android в своей жизни. Я постараюсь максимально упростить. Давайте сделаем шаг назад и просмотрим основания.

Мы знаем, что мобильные устройства влияют на многие факторы. К примеру, конфигурация постоянно меняется, а локаль может изменяться явно или неявно.

Все эти изменения приводят к повторному созданию программ, чтобы они могли выбрать правильные ресурсы, которые лучше всего соответствуют текущей конфигурации. Портрет, пейзаж, планшет, китайский, немецкий и т.д. Ваши программы необходимы лучшие ресурсы, чтобы обеспечить наилучший опыт пользователя. Контекст отвечает за предоставление наилучших ресурсов.

Попытайтесь ответить на этот вопрос:
В настоящее время пользовательская конфигурация находится в портретной ориентации, и вы хотите получить доступ к ресурсам альбомной ориентации. Или местный пользовательский стандарт en и вы хотите получить доступ uk ресурсов Как ты это сделаешь?

Ниже приведены некоторые магические методы из контекста:

pm0XjARPJfj3jaVp6O846mROEem3fKcYVOS1

Существует много методов createX, но нас интересуют в основном createConfigurationContext. Вот как это можно использовать:

Configuration configuration = getResources().getConfiguration();configuration.setLocale(your_custom_locale);context = createConfigurationContext(configuration);

Вы можете получить любой тип пожелаемого контекста. Когда вы вызываете любой метод в новом контексте, который вы получили, вы получите доступ к ресурсам на основе установленной вами конфигурации.

Я знаю, что это удивительно. Вы можете отправить мне благодарственную открытку.

Аналогично вы можете создать тематический контекст и использовать его для увеличения количества просмотров соответствующей темой.

ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.YOUR_THEME);

Давайте вернемся к сложному вопросу, который мы задали выше, и обсудим контекст деятельности.

Какая разница между this, getApplicationContext() и getBaseContext()?

Это возможные способы, которыми вы можете завладеть Context, когда вы находитесь в Activity объем.

this указывает на саму активность, наш контекст пользовательского интерфейса и контекст короткой жизни. getApplicationContext() указывает на экземпляр вашей программы, не являющийся интерфейсным и длительным контекстом.

baseContext является основой вашего контекста активности, который можно установить с помощью шаблона делегата. Вы уже знаете, что можете создать контекст с любым xyz нужную вам конфигурацию. Вы можете совмещать свои xyz знание конфигурации с базовым контекстом и ваша активность будет загружать ресурсы по вашему желанию.

Вот метод, который вы можете использовать:

@Overideprotected void attachBaseContext (Context base) {super.attachBaseContext(useYourCustomContext);}

один раз BaseContext Добавляется, что ваша активность будет делегировать вызовы этому объекту. Если вы не присоединитесь к Activity, он остается baseContext и вы получаете активность, когда звоните getBaseContext.

Вывод

Можно сказать, что контекст – это жизнь вашего приложения для Android. С точки зрения Android, это ваше приложение. Вы почти ничего не можете поделать без контекста. Без этого ваше приложение является простым кодом Java.

Контекст + Java-код => Android

Хороший или плохой, у нас есть дизайн, и мы должны использовать его как можно лучше. Из первой части настоящей статьи мы узнали, что мы используем его для связи между компонентами, создания экземпляров компонентов и компонентов доступа.

В следующей части мы узнали, что контекст может быть UI или NonUI, кратковременным или продолжительным.

После этого мы узнали, что нужно тщательно выбирать контекст, иначе придется столкнуться с утечками памяти и другими проблемами интерфейса.

Наконец, вы увидели, что Context отвечает за загрузку лучших ресурсов для вашего приложения, и вы можете настроить его так, как хотите. Мы также узнали разницу между this, applicationContext и baseContext.

Многие разработчики советуют использовать только контекст программы. Не используйте контекст программы повсюду из-за страха перед утечкой памяти. Поймите первопричину и всегда используйте правильный контекст в нужном месте.

Вы, мой дорогой друг, теперь мастер Android Context. Вы можете предложить следующую тему, которую вы хотите понять. Нажмите здесь, чтобы предложить.

Ниже приведены ссылки из оригинальной серии Освоение контекста Android на моем блоге.

Глава 1

Что такое контекст? Зачем это нужно и какие варианты использования в повседневной разработке?

Глава 2

Упрощение контекста. Мы обсудим, сколько типов контекста существует и какие из них вы должны использовать.

Глава 3

Где использовать контекст пользовательского интерфейса, а где использовать не контекст пользовательского интерфейса. Использование контекста в неправильном месте может привести к утечке памяти.

Глава 4

Мой контекст пользовательского интерфейса также предлагает мне несколько типов контекста. Давайте ответим на этот вопрос и посмотрим, как избежать распространённых подводных камней.

Обучение

Знаете ли вы, что много раз ваше приложение аварийно завершает работу из-за того, что ваши разработчики неправильно используют Context? Давайте учиться вместе. Предлагаю обучение по Android, Java и Git.

Хотите освоить темы для Android? Просмотрите нашу серию с более чем 3 тысячами голосов.

Не стесняйтесь поделиться своими отзывами и вопросами. Счастливый код.

Следите за мной на Medium и Twitter, чтобы получать обновления.

Добавить комментарий

Ваш адрес email не будет опубликован.