- Different ways to get Context in Android
- The “this” Keyword
- Get current activity context : View.getContext()
- Get App-level context : getApplicationContext()
- Get Original context : getBaseContext()
- Get Context from Fragment : getContext()
- Get parent Activity : getActivity()
- Non-nullable Context : requireContext() and requireActivity()
- Context в Android приложении
- Что такое Context?
- Контекст приложения
- Контекст Activity
- getContext() в ContentProvider
- Когда нельзя использовать getApplicationContext()?
- Правило большого пальца
- 16 советов по разработке для андроид на языке Kotlin. Часть 2
- Описание объектов
- Вспомогательные объекты
- Глобальные константы
- Расширения
- Современная Android разработка на Kotlin. Часть 2
- Архитектура MVVM + Паттерн Repository + Android Manager Wrappers
- Пару слов об Архитектуре в мире Андроид
- Что такое MVVM паттерн?
- Пример кода
Different ways to get Context in Android
Context is one of the important and most used property. You need Context to perform a lot of things on Android. Be is displaying a toast or Accessing database, you use context a lot while building Android app.
Context is property, well, which can give you the context of whats happening on the Screen/Activity it belongs to. It contains information about what Views are there, How they are laid out etc.
So, it is important to know different types of Context and methods you can call to get context. Lets get started.
The “this” Keyword
The this keyword in general sense refers to current class instance. So, when use “this” keyword inside an Activity, it refers to that Activity instance. And as Activity is subclass of “Context”, you will get context of that activity.
If you are not directly inside Activity, for example inside an OnClickListener, you can get the current context by referencing with Activity name like MainActivity.this (Java) or this@MainActivity (Kotlin)
Get current activity context : View.getContext()
This method can be called on a View like textView.getContext() . This will give the context of activity in which the view is currently hosted in.
Get App-level context : getApplicationContext()
If you need to access resources which are out of scope of specific activity, like when accessing SharedPreferences, displaying Toast message etc. you can use this.
So unlike activity context, which will be destroyed when close an activity, Application Context the application wide context which won’t get destroyed until you completely close application.
You can directly access application context by calling getApplicationContext() or by calling on activity context like context.getApplicationContext()
Get Original context : getBaseContext()
This method is only useful when you are using ContextWrapper. You can get the original context which was wrapped by ContextWrapper by calling contextWrapper.getBaseContext()
( ContextWrapper is a wrapper class, using which you can override any method of Context, while still retaining the original context)
Get Context from Fragment : getContext()
When you call getContext() from an Fragment, you will get the context of the activity in which that fragment is hosted in.
Get parent Activity : getActivity()
You can get the parent activity from a Fragment by calling getActivity() .
💡Difference : Both getContext() and getActivity() are not much different in most cases, when you just need a context as both will get Parent activity context. Except for some cases, for example when using ContextWrapper, getContext() and getActivity() can point to different contexts.
Non-nullable Context : requireContext() and requireActivity()
These methods are same but “NotNull” versions of getContext() and getActivity() respectively. Usually, if a fragment is detached from Activity, you will get “null” value when you call getContext() or getActivity() . So even when you are sure the context won’t be null, you still have to add null checks (especially in Kotlin) because they return Nullable type.
But requireContext() and requireActivity() will throw IllegalStateException instead of returning null, if there is no context.
These methods are mainly useful when you using Kotlin and you need a Non-Nullable Context. So using these methods instead, is matter of personal preference.
So, did you learn something new? If you did, please clap and share the post. 😄
Источник
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 или другого компонента, даже временно, используйте ссылку на контекст приложения.
Источник
16 советов по разработке для андроид на языке Kotlin. Часть 2
Всем привет. В преддверии старта базового курса по Android-разработке, продолжаем делиться полезным материалом.
Перед прочтением этих советов вам желательно ознакомиться с документацией Kotlin и самостоятельно изучить язык на сайте try.kotlinlang.org . Поскольку эти советы направлены именно на использование Kotlin в контексте разработки под Android, у вас также должен быть опыт работы с Android SDK. Также желательно ознакомиться с плагином Kotlin и использованием Kotlin с Android Studio от JetBrains (создателей Kotlin)
Описание объектов
Описания объектов допускают только синглетоны, которые нельзя принять за класс с возможностью создания экземпляров. Поэтому вам не нужно хранить синглеты как переменные статического класса или в классе Application.
Например, если у меня есть служебный класс со статическими методами, связанными с потоками, а я хочу получить доступ ко всему приложению, можно сделать вот так:
ThreadUtil можно вызвать позже таким же способом, как и при вызове метода статического класса:
Это означает, что больше не нужно имитировать поведение статического класса при помощи закрытого конструктора и не нужно выяснять, где хранится экземпляр. Объекты, по сути, являются первоначальными элементами языка. По этому же принципу мы создаем объекты вместо внутренних классов:
Оба по сути делают одно и то же — создают один экземпляр класса как объявленный объект.
Вспомогательные объекты
На первый взгляд в Kotlin нет статических переменных и методов. В данном языке отсутствуют эти концепции, зато есть концепция вспомогательных объектов. Они являются одноэлементными объектами в классе, содержащими методы и переменные, к которым вы можете обращаться статическим способом. Сопутствующий объект допускает определенные константы и методы, подобные статическим классам в Java. С его помощью вы можете следовать шаблону фрагментов newInstance.
Взгляните на сопутствующий объект в его простейшей форме:
В Android мы обычно используем статические методы и переменные для создания статических фабрик для фрагментов. Например:
Создание Intent похоже на аналогичное действие в Java:
Этот паттерн хорош, так как он уменьшает вероятность того, что у Intent или Fragment будут отсутствовать необходимые для отображения пользовательского или любого другого контента данные. Сопутствующие объекты — это способ сохранить форму статического доступа в Kotlin, и их следует использовать как компенсацию отсутствия классов.
Глобальные константы
Kotlin позволяет вам определять константы, которые видны в одном месте приложения (если это применимо). Но область действия констант по возможности должна быть максимально уменьшена. А в ситуациях, когда нужно, чтобы область была глобальной, в Kotlin есть отличный способ сделать это без необходимости использовать класс констант. Что-то типа:
Потом их можно использовать как константы в любом месте проекта:
Констант в проекте должно быть как можно меньше, чтобы уменьшить его сложность. Если у вас есть значение, которое относится только к пользовательскому классу, лучше поместить его во вспомогательный объект.
Расширения
Расширения полезны, потому что они позволяют добавлять функциональность класса, не наследуя его. Например, как добавить к Activity какой-нибудь метод, типа hideKeyboard() ? С помощью расширений можно легко это сделать:
Расширения полезны тем, что они:
- помогают улучшить читабельность кода;
- избавляют от необходимости создавать служебные классы и методы.
Можно пойти дальше и улучшить архитектуру кода. Представьте, что у вас есть базовая модель, например, Article, которая рассматривается как класс данных, извлеченных из источника по API:
Нужно определить релевантность Article для пользователя на основе какой-то формулы. Должны ли вы поместить её непосредственно в класс Article? И если модель должна содержать только данные из API, не более того, снова можно использовать расширения:
В настоящее время это простая возможность проверки присутствия темы Article в списке любимых тем пользователя.
Эта логика может меняться в зависимости от того, где вы хотите проверить эти и другие атрибуты пользовательского поведения. Поскольку эта логика поддерживается в некоторой степени независимо от модели Article, вы можете изменить ее в зависимости от цели, метода и его способности быть измененным.
Источник
Современная Android разработка на Kotlin. Часть 2
Привет, Хабр! Представляю вашему вниманию перевод статьи «Modern Android development with Kotlin (Part 2)» автора Mladen Rakonjac.
Примечание. Данная статья является переводом циклов статей от Mladen Rakonjac, дата статьи: 23.09.2017. GitHub. Начав читать первую часть от SemperPeritus обнаружил, что остальные части почему-то не были переведены. Поэтому и предлагаю вашему вниманию вторую часть. Статья получилась объёмной.
«Очень сложно найти один проект, который охватывал бы всё новое в разработке под Android в Android Studio 3.0, поэтому я решил написать его.»
В этой статье мы разберём следующее:
- Android Studio 3, beta 1 Часть 1
- Язык программирования Kotlin Часть 1
- Варианты сборки Часть 1
- ConstraintLayout Часть 1
- Библиотека привязки данных Data Binding Часть 1
- Архитектура MVVM + Паттерн Repository + Android Manager Wrappers
- RxJava2 и как это помогает нам в архитектуре Part 3
- Dagger 2.11, что такое внедрение зависимости, почему вы должны использовать это Part 4
- Retrofit (with Rx Java2)
- Room (with Rx Java2)
Архитектура MVVM + Паттерн Repository + Android Manager Wrappers
Пару слов об Архитектуре в мире Андроид
Довольно долгое время андроид-разработчики не использовали какую-либо архитектуру в своих проектах. В последние три года вокруг неё в сообществе андроид-разработчиков поднялось много шумихи. Время God Activity прошло и Google опубликовал репозиторий Android Architecture Blueprints, с множеством примеров и инструкций по различным архитектурным подходам. Наконец, на Google IO ’17 они представили Android Architecture Components — коллекцию библиотек, призванных помочь нам создавать более чистый код и улучшить приложения. Component говорит, что вы можете использовать их все, или только один из них. Впрочем, я нашёл их все реально полезными. Далее в тексте и в следующих частях мы будет их использовать. Сперва я в коде доберусь до проблемы, после чего проведу рефакторинг, используя эти компоненты и библиотеки, чтобы увидеть, какие проблемы они призваны решить.
Существуют два основных архитектурных паттерна, которые разделяют GUI-код:
- MVP
- MVVM
Трудно сказать, что лучше. Вы должны попробовать оба и решить. Я предпочитаю MVVM, используя lifecycle-aware компоненты и я напишу об этом. Если вы никогда не пробовали использовать MVP, на Medium есть куча хороших статей об этом.
Что такое MVVM паттерн?
MVVM — это архитектурный паттерн, раскрывается как Model-View-ViewModel. Я думаю это название смущает разработчиков. Если бы я был тем, кто придумал ему имя, я бы назвал его View-ViewModel-Model, потому что ViewModel находится посередине, соединяя View и Model.
View — это абстракция для Activity, Fragment‘а или любой другой кастомной View (Android Custom View). Обратите внимание, важно не путать эту View с Android View. View должна быть тупой, мы не должны писать какую-либо логику в неё. View не должна содержать данные. Она должна хранить ссылку на экземпляр ViewModel и все данные, которые нужны View, должны приходить оттуда. Кроме того, View должна наблюдать за этими данными и layout должен поменяться, когда данные из ViewModel изменятся. Подводя итог, View отвечает за следующее: вид layout’а для различных данных и состояний.
ViewModel — это абстрактное имя для класса, содержащего данные и логику, когда эти данные должны быть получены и когда показаны. ViewModel хранит текущее состояние. Также ViewModel хранит ссылку на одну или несколько Model‘ей и все данные получает от них. Она не должна знать, к примеру, откуда получены данные, из базы данных или с сервера. Кроме того, ViewModel не должна ничего знать о View. Более того, ViewModel вообще ничего не должна знать о фреймворке Android.
Model — это абстрактное имя для слоя, который подготавливает данные для ViewModel. Это класс, в котором мы будем получать данные с сервера и кэшировать их, или сохранять в локальную базу данных. Заметьте, что это не те же классы, что и User, Car, Square, другие классы моделей, которые просто хранят данные. Как правило, это реализация шаблона Repository, который мы рассмотрим далее. Model не должна ничего знать о ViewModel.
MVVM, если реализован правильно, это отличный способ разбить ваш код и сделать его более тестируемым. Это помогает нам следовать принципам SOLID, поэтому наш код легче поддерживать.
Пример кода
Сейчас я напишу простейший пример, показывающий как это работает.
Для начала, давайте создадим простенькую Model, которая возвращает некую строчку:
Обычно получение данных — это асинхронный вызов, поэтому мы должны ждать его. Чтобы сымитировать это, я поменял класс на следующий:
Я создал интерфейс OnDataReadyCallback с методом onDataReady . И теперь метод refreshData реализует (имплементирует) OnDataReadyCallback . Для имитации ожидания я использую Handler . Раз в 2 секунды метод onDataReady будет вызываться у классов, реализующих интерфейс OnDataReadyCallback .
Давайте создадим ViewModel:
Как вы можете видеть, здесь есть экземпляр RepoModel , text , который будет показан и переменная isLoading , которая хранит текущее состояние. Давайте создадим метод refresh , отвечающий за получение данных:
Метод refresh вызывает refreshData у RepoModel , который в аргументах берёт реализацию OnDataReadyCallback . Хорошо, но что такое object ? Всякий раз, когда вы хотите реализовать (implement) какой-либо интерфейс или унаследовать (extend) какой-либо класс без создания подкласса, вы будете использовать объявление объекта (object declaration). А если вы захотите использовать это как анонимный класс? В этом случае вы используете object expression:
Когда мы вызываем refresh , мы должны изменить view на состояние загрузки и когда данные придут, установить у isLoading значение false .
Также мы должны заменить text на
Обратите внимание, что я использую val вместо var, потому что мы изменим только значение в поле, но не само поле. И если вы захотите проинициализировать его, используйте следующее:
Давайте изменим наш layout, чтобы он мог наблюдать за text и isLoading. Для начала, привяжем MainViewModel вместо Repository:
- Изменим TextView для наблюдения за text из MainViewModel
- Добавим ProgressBar, который будет виден только если isLoading true
- Добавим Button, которая при клике будет вызывать метод refresh из MainViewModel и будет кликабельна только в случае isLoading false
Если вы сейчас запустите, то получите ошибку View.VISIBLE and View.GONE cannot be used if View is not imported . Что ж, давайте импортируем:
Хорошо, с макетом закончили. Теперь закончим со связыванием. Как я сказал, View должна иметь экземпляр ViewModel :
Источник