- Room android kotlin livedata
- Урок 2. LiveData
- Подключение библиотеки
- Теория
- Получение данных из LiveData
- Нюансы поведения
- Отправка данных в LiveData
- Android LiveData на Kotlin с использованием Retrofit и coroutines
- Русские Блоги
- Android Room By Kotlin
- Введение в демо
- Введение в комнату
- 1. Создайте пустой проект.
- 2. Обновите файл Gradle.
- 3. Создайте объект
- 4. Создайте Дао
- Что такое Дао?
- Написать Дао
- 5. Класс LiveData
- 7, добавьте RoomDatabase
- Что такое RoomDatabase?
- Написать RomDatabase
- 8. Создать репозиторий
- Что такое репозиторий?
- Написать репозиторий
- 9. Создайте ViewModel.
- Что такое VIewModel?
- Зачем использовать ViewModel
- viewModelScope
- Реализовать ViewModel
- 10. Наконец
Room android kotlin livedata
Room is a part of the Android Architecture components which provides an abstraction layer over SQlite which allows for a more robust database acces while still providing the full power of SQlite. You can read about Room in details here.
Room 2.1 (SQLite Persistence Library) added the support for coroutines. Now you can add the suspend keyword to DAO class methods and ensures that they are not executed in the MainThread.
Coroutines are light-weight threads. They are launched with launch coroutine builder in a context of some CoroutineScope.
LiveData is an observable data holder, part of the Android Jetpack. LiveData considers an observer, which is represented by the Observer class, to be in an active state if its lifecycle is in the STARTED or RESUMED state. LiveData only notifies active observers about updates.
First, we need to add the needed dependencies that will enable us to use the Room library. We can do so with some simple lines in the build.gradle (Module:app) file. Last version of Room here. Last version of Lifecycle here.
The Room library consists of 3 major components: Entity, DAO (Database Access Object), Database.
The Entity represents a table within the database and has to be annotated with @Enity . Each Entity consist of a minimum of one field has to define a primary key.
In Room you use DAO to access and manage your data. The DAO is the main component of Room and includes methodes that offer access to your apps database it has to be annotated with @Dao . DAOs are used instead of query builders and let you seperate differend components of your database e.g. current data and statistics, which allows you to easily test your database.
Serves as the database holder an is the main accespoint to your relational data. It has to be annotated with @Database and extents the RoomDatabase . It also containes and returns the Dao (Database Access Object).
This is a class where we will check whether to fetch data from API or local database, or you can say we are putting the logic of database fetching in this class.
This is the part of lifecycle library; this will help you to provide data between repository and UI. This survives the data on configuration changes and gets the existing ViewModel to reconnect with the new instance of the owner.
SQLite debug tools
- Stetho is a debug bridge for Android that allows you to connect to a device and to inspect your app using Chrome Developer Tools.
- SQLScout is a plugin for Android Studio and Intellij IDEA which allows you to connect to SQLite databases, browse tables and schemes.
- Liya
- SQLPro for SQLite
Источник
Урок 2. LiveData
В этом уроке рассмотрим основные возможности LiveData. Как подписаться на его данные. Как помещать в него данные. Как он взаимодействует со своими подписчиками.
Полный список уроков курса:
Подключение библиотеки
В build.gradle файл проекта добавьте репозитарий google()
В build.gradle файле модуля добавьте dependencies:
Если у вас студия ниже 3.0 и старые версии Gradle и Android Plugin, то подключение будет выглядеть так:
Иногда может возникнуть конфликт с support library. Будет выдавать такую ошибку: Error:Program type already present: android.arch.lifecycle.LiveData
В таком случае попробуйте указать последние версии двух этих библиотек.
Теория
LiveData — хранилище данных, работающее по принципу паттерна Observer (наблюдатель). Это хранилище умеет делать две вещи:
1) В него можно поместить какой-либо объект
2) На него можно подписаться и получать объекты, которые в него помещают.
Т.е. с одной стороны кто-то помещает объект в хранилище, а с другой стороны кто-то подписывается и получает этот объект.
В качестве аналогии можно привести, например, каналы в Telegram. Автор пишет пост и отправляет его в канал, а все подписчики получают этот пост.
Если вы знакомы с RxJava, то LiveData напомнит вам BehaviourSubject. Методом onNext вы передаете ему данные, а он передает эти данные своим подписчикам. Плюс, все новые подписчики сразу получают последнее значение.
Казалось бы, ничего особо в таком хранилище нет, но есть один очень важный нюанс. LiveData умеет определять активен подписчик или нет, и отправлять данные будет только активным подписчикам. Предполагается, что подписчиками LiveData будут Activity и фрагменты. А их состояние активности будет определяться с помощью их Lifecycle объекта, который мы рассмотрели в прошлом уроке.
Получение данных из LiveData
Давайте рассмотрим пример.
Пусть у нас есть некий синглтон класс DataController из которого можно получить LiveData .
DataController периодически что-то там внутри себя делает и обновляет данные в LiveData. Как он это делает, мы посмотрим чуть позже. Сначала посмотрим, как Activity может подписаться на LiveData и получать данные, которые помещает в него DataController.
Код в Activity будет выглядеть так:
Получаем LiveData из DataController, и методом )» target=»_blank» rel=»noopener noreferrer»>observe подписываемся. В метод observe нам необходимо передать два параметра:
Первый — это LifecycleOwner. Напомню, что LifecycleOwner — это интерфейс с методом getLifecycle. Activity и фрагменты в Support Library, начиная с версии 26.1.0 реализуют этот интерфейс, поэтому мы передаем this.
LiveData получит из Activity его Lifecycle и по нему будет определять состояние Activity. Активным считается состояние STARTED или RESUMED. Т.е. если Activity видно на экране, то LiveData считает его активным и будет отправлять данные в его колбэк.
Если предыдущие два абзаца состоят из кучи незнакомых для вас слов, то посмотрите Урок 1. Lifecycle. Там мы подробно разобрали объект Lifecycle и его состояния.
Второй параметр — это непосредственно подписчик, т.е. колбэк, в который LiveData будет отправлять данные. В нем только один метод onChanged. В нашем примере туда будет приходить String.
Теперь, когда DataController поместит какой-либо String объект в LiveData, мы сразу получим этот объект в Activity, если Activity находится в состоянии STARTED или RESUMED.
Нюансы поведения
Распишу сразу несколько важных моментов в поведении LifeData.
Если Activity было не активно во время обновления данных в LiveData, то при возврате в активное состояние, его observer получит последнее актуальное значение данных.
В момент подписки, observer получит последнее актуальное значение из LiveData.
Если Activity будет закрыто, т.е. перейдет в статус DESTROYED, то LiveData автоматически отпишет от себя его observer.
Если Activity в состоянии DESTROYED попробует подписаться, то подписка не будет выполнена.
Если Activity уже подписывало свой observer, и попробует сделать это еще раз, то просто ничего не произойдет.
Вы всегда можете получить последнее значение LiveData с помощью его метода getValue.
Как видите, подписывать Activity на LiveData — это удобно. Поворот экрана и полное закрытие Activity — все это корректно и удобно обрабатывается автоматически без каких-либо усилий с нашей стороны.
Отправка данных в LiveData
Мы разобрались, как получать данные из LiveData, и каким образом при этом учитывается состояние Activity. Теперь давайте посмотрим с другой стороны — как передавать данные в LiveData.
В классе DataController переменная LiveData будет выглядеть так:
Наружу мы передаем LiveData, который позволит внешним объектам только получать данные. Но внутри DataController мы используем объект MutableLiveData, который позволяет помещать в него данные.
Чтобы поместить значение в MutableLiveData, используется метод setValue:
Этот метод обновит значение LiveData, и все его активные подписчики получат это обновление.
Метод setValue должен быть вызван из UI потока. Для обновления данных из других потоков используйте метод postValue. Он перенаправит вызов в UI поток. Соответственно, подписчики всегда будут получать значения в основном потоке.
Чуть более подробный пример с LiveData мы рассмотрим в Уроке 4, когда будем изучать ViewModel.
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Android LiveData на Kotlin с использованием Retrofit и coroutines
Так же рассмотрен пример применения современного Coroutines в связке с репозитарием на Retrofit
Retrofit coroutines extension
kotlin-coroutines-retrofit
Расширение для Retrofit на Kotlin. Это всего два файла. Я просто добавил их в проект. Вы можете подключить их через Dependency в Gradle. На Github есть примеры использования.
Также подключаем Adapter addCallAdapterFactory(CoroutineCallAdapterFactory()).
ServerAPI и Repository находятся в одном файле
Реализацией REST API на Kotlin. Она не имеет каких либо специфичных изменений
Далее рассмотрим Repository. Это основной сервис получения LiveData. Инициализируем LiveData состоянием загрузки: Resource.loading(null). Далее ожидаем окончание запроса awaitResult() Этот вызов должен быть в блоке Coroutin async(UI)
По окончанию запроса мы можем хэндлить результат. Если все хорошо результат будет сохранен в mutableLiveData.value = Resource.success(result.value) Важный момент — это должена быть ссылка на новый экземпляр, иначе observer LiveData не отработает. see: new Resource<>(SUCCESS, data, null);
Для обработки ошибок и передачи состояния в Fragment используется Wrapper — Resource .
Он хранить три состояния:
StoresViewModel запрашивает данные у репозитория и сохраняет во внутренней переменной stores
Для передачи параметров в ViewModel расширим стандартную ViewModelProviders
Например для передачи в LoginViewModel надо два параметра (Login,Password). Для передачи токена в StoresViewModel используется один (Token)
Использование наблюдателя Observer за изменением данных:
Для хранения Token и использования его во всем приложении я применил библиотеку/расширение от Fabio Collini. Применение хорошо описано в его статье. Ссылка есть на странице в Github или ниже в этой статье.
Источник
Русские Блоги
Android Room By Kotlin
Введение в демо
Эта демонстрация представляет собой простое приложение, демонстрирующее использование синтаксиса Room в Kotlin.
Введение в комнату
Библиотека сохраняемости Room предоставляет уровень абстракции на основе SQLite, позволяя пользователям в полной мере использовать мощные функции SQLite, пользуясь более надежным механизмом доступа к базе данных.
Эта библиотека помогает вам создать локальную базу данных на устройстве, на котором запущено приложение.
1. Создайте пустой проект.
2. Обновите файл Gradle.
Библиотеку компонентов необходимо добавить в файл Gradle
в вашем build.gradle Внесите следующие изменения в (Модуль: приложение):
Примените его, добавив плагин Kotlin для обработки аннотаций kapt к другим плагинам, определенным в верхней части файла (Module: app).
bulid.gradle
В коде dependencies Добавьте следующий код в конец блока.
ПозжеПроект build.gradle (Project)
Здесь вы также можете перейти на официальный сайт, чтобы найти номер последней версииссылка на сайт
3. Создайте объект
Room позволяет создавать таблицы через Entity. Начнем сейчас.
Проанализируйте значение аннотации @ в следующем коде
- @Entity(tableName = «todo_database»)
каждый @Entity Класс представляет собой таблицу SQLite. Аннотируйте свой класс, чтобы показать, что это класс сущности. Если вы хотите, чтобы имя таблицы отличалось от имени класса, вы можете указать имя таблицы. Эта таблица называется «todo_database» - @PrimaryKey
Каждой сущности нужен первичный ключ. Используйте здесь autoGenerate = true Для автоматического создания - @ColumnInfo(name = «todo_title»)
Если вы хотите, чтобы имя столбца в таблице отличалось от имени переменной-члена, укажите это имя. Это назовет столбец «todo_title».
4. Создайте Дао
Что такое Дао?
В DAO (объект доступа к данным) укажите запросы SQL и свяжите их с вызовами методов. Компилятор проверяет SQL и генерирует запросы @Insert для общих запросов (например) из удобных комментариев. Room использует DAO для создания чистого API для вашего кода.
DAO должен быть интерфейсом или абстрактным классом.
По умолчанию все запросы должны выполняться в отдельном потоке.
В Room есть поддержка сопрограмм, что позволяет аннотировать ваши запросы с помощью модификатора приостановки, а затем вызывать их из сопрограммы или другой приостановленной функции.
Написать Дао
Давайте напишем DAO, который предоставляет следующий запрос:
- Расположите все заголовки в алфавитном порядке
- Вставить Todo
- Удалить все Todo
- TodoDao Интерфейс; Дао должен быть интерфейсом или абстрактным классом.
- В @Dao В аннотации указано, что это класс комнаты Дао.
- suspend fun insert(todo: Todo) Объявите функцию паузы для вставки Todo.
- Аннотация @Insert — это специальная аннотация метода DAO, вам не нужно предоставлять какой-либо SQL! (Существуют также аннотации @Delete и @Update для удаления и обновления строк, но они не используются в этом приложении.)
- onConflict = OnConflictStrategy.IGNORE Если Todo, выбранный в политике конфликтов, в точности совпадает с существующим Todo в списке, слово будет проигнорировано.
- suspend fun deleteAll() Объявите функцию паузы для удаления всех Todos.
- на @Query Использование слишком много и разное, пожалуйста, проверьте информацию самостоятельно
5. Класс LiveData
При изменении данных обычно требуются некоторые меры, например отображение обновленных данных в пользовательском интерфейсе. Это означает, что вы должны наблюдать за данными, чтобы вы могли реагировать на их изменение.
В зависимости от того, как хранятся данные, это может быть сложно. Наблюдение за изменениями данных между несколькими компонентами приложения может создать четкий и строгий путь зависимости между компонентами. Это очень затрудняет тестирование и отладку.
LiveData, класс библиотеки жизненного цикла для наблюдения за данными, может решить эту проблему. LiveData использует возвращаемое значение типа в описании метода, а затем Room генерирует все необходимые коды для обновления базы данных LiveData.
отражен в приведенном выше блоке кода следующим образом
Позже в этой демонстрации изменения данных будут отслеживаться через Observer.
7, добавьте RoomDatabase
Что такое RoomDatabase?
- Комната — это уровень базы данных поверх базы данных SQLite.
- Room отвечает за выполнение общих задач, которые ранее выполнялись NET.
- Room использует DAO для отправки запросов к своей базе данных.
- По умолчанию, чтобы избежать снижения производительности пользовательского интерфейса, Room не позволяет выполнять запросы в основном потоке. Когда запрос Room возвращает LiveData, запрос будет автоматически выполняться асинхронно в фоновом потоке.
- Room обеспечивает проверку операторов SQLite во время компиляции.
Написать RomDatabase
Класс RoomDatabase должен быть абстрактным и может расширять RoomDatabase. Обычно для всего приложения требуется только один экземпляр базы данных Room.
Давайте сделаем это сейчас. Создайте файл класса Kotlin с именем WordRoomDatabase и добавьте следующий код:
Взглянем на код:
- Room Класс базы данных должен быть abstract И расширить RoomDatabase
- Вы используете класс аннотации в качестве базы данных Room, @Database И используйте параметр комментария, чтобы объявить сущность, принадлежащую базе данных, и установить номер версии. Каждой сущности соответствует таблица, которая будет создана в базе данных. Миграция базы данных выходит за рамки этой лаборатории кода, поэтому exportSchema Установить здесь как false Чтобы избежать генерации предупреждений. В реальном приложении вам следует рассмотреть возможность создания каталога для Room для экспорта архитектуры, чтобы текущую архитектуру можно было проверить в системе контроля версий.
- Вы переходите за каждый @Dao Создайте абстрактный метод «получения», чтобы база данных предоставляла свой DAO.
- Мы определили singleton , TodoRoomDatabase Чтобы предотвратить одновременное открытие нескольких экземпляров базы данных.
- getDatabase Вернуться к синглтону. Он будет использовать построитель базы данных Room при первом доступе к базе данных. RoomDatabase Создайте объект в контексте приложения класса TodoRoomDatabase И назовите его для создания базы данных «todo_database».
8. Создать репозиторий
Что такое репозиторий?
Класс репозитория абстрагирует доступ к нескольким источникам данных. Репозиторий не является частью библиотеки архитектурных компонентов, но является рекомендуемым разделением кода и передовыми методами архитектуры. Класс Repository предоставляет чистый API для доступа к данным остальной части приложения.
Написать репозиторий
Создайте файл класса Kotlin с именем TodoRepository И вставьте в него следующий код:
- DAO передается конструктору репозитория, а не всей базе данных. Это потому, что ему нужен только доступ к DAO, потому что DAO содержит все методы чтения / записи базы данных. Нет необходимости предоставлять всю базу данных в репозиторий.
- Todo Список является государственной собственностью. по LiveData Из Room Получите список слов для инициализации; причина, по которой мы можем это сделать, заключается в том, что мы определили getAlphabetizedTodoList возвращение LiveData Методы. Room Все запросы выполняются в отдельных потоках. Потом, когда LiveData Когда данные изменились, observed Наблюдатель будет уведомлен в основном потоке.
- В suspend Модификатор сообщает компилятору, что это нужно вызывать из сопрограммы или другой функции паузы.
9. Создайте ViewModel.
Что такое VIewModel?
ViewModel Роль заключается в предоставлении пользовательского интерфейса данных и сохранении изменений конфигурации. ViewModel Выступает в качестве коммуникационного центра между репозиторием и пользовательским интерфейсом. Вы также можете использовать ViewModel Делитесь данными между клипами. ViewModel Это часть библиотеки жизненного цикла.
Зачем использовать ViewModel
ViewModel Сохраняйте данные пользовательского интерфейса приложения с учетом жизненного цикла, чтобы сохранить изменения конфигурации. Данные пользовательского интерфейса приложения Activity Класс и Fragment Разделите классы, чтобы лучше следовать принципу единой ответственности: ваши действия и фрагменты отвечают за вывод данных на экран, а вы ViewModel Может отвечать за сохранение и обработку всех данных, требуемых пользовательским интерфейсом.
в ViewModel , LiveData Используется для переменных данных, которые будет использовать или отображать пользовательский интерфейс. Использование LiveData дает несколько преимуществ:
- Вы можете поставить наблюдателей на данные (вместо опроса на предмет изменений) и только
Обновляйте пользовательский интерфейс только при фактическом изменении данных. - Библиотека ресурсов и пользовательский интерфейс полностью разделены.
- Нет обращений к базе данных от ViewModel (Все это обрабатывается в репозитории), чтобы сделать код более тестируемым.
viewModelScope
В Котлине все сопрограммы запускаются внутри CoroutineScope . Осциллограф контролирует жизненный цикл сопрограммы через ее работу. При отмене операции области консолидации будут отменены все сопрограммы, запущенные в области консолидации.
AndroidX lifecycle-viewmodel-ktx Библиотека добавлена viewModelScope Функция расширения класса ViewModel Чтобы вы могли использовать диапазон.
Реализовать ViewModel
Создайте для этого файл класса Kotlin и добавьте следующий код:
10. Наконец
Теперь нам нужно только вызвать метод вставки во ViewModel для вставки данных.
Конкретный код тестового интерфейса (RecyclerView и т. Д.) Показан по ссылке Github ниже.
Источник