Изучаем LiveData в Android: postValue или setValue?

Как передавать данные при синхронной и асинхронной работе через LiveData
2 минуты1751

Разработчикам Android часто приходится иметь дело с различными данными. Данные с одного экрана могут использоваться на другом. А ещё можно поменять внешний вид экрана, если данные обновились. Основная задача состоит в том, чтобы наладить эффективное взаимодействие между экраном и источником данных. Лучший способ это сделать — использовать LiveData, которая является частью Android Jetpack.

Чаще всего в LiveData используют методы setValue и postValue. Если судить по названию, кажется, что они выполняют одинаковую работу. Но на самом деле это не так. 

Давайте разбираться, в чём разница.

Что такое LiveData?

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

Если говорить простыми словами, LiveData — это контейнер, который следит за жизненным циклом экрана и снабжает его данными, когда это уместно. Например, если активити находится на переднем плане и видна пользователю. Ценность такого подхода заключается в том, что LiveData не будет снабжать ваш экран данными, если он свёрнут или закрыт. Но как только экран появится перед пользователем, обновление данных возобновится.

Это даёт LiveData несколько преимуществ:

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

Дополнительные материалы по LiveData.

Разница между setValue и postValue

Разберём на примере, зачем нужны такие похожие методы. Предположим, вам нужно обновить данные на экране с помощью LiveData. Вы можете сделать это в основном потоке приложения (Main thread) или в отдельном. При обновлении в основном потоке вы используете setValue у класса MutableLiveData. А при обновлении данных для основного потока из фонового нужно использовать метод postValue. Это значит, что метод setValue уместен в основном потоке приложения, а postValue — если данные приходят из фонового потока. 

Вот чек-лист, чтобы не запутаться, когда какой метод нужен:

  • Если вы выполняете работу в основном потоке, то setValue и postValue будут работать одинаково.
  • Если вы выполняете работу в фоновом потоке, то можете использовать только postValue. Дело в том, что данные в LiveData изменятся сразу, а вот их обновление в основном потоке будет происходить асинхронно при помощи Handler.

В коде это будет выглядеть так:

// setValue
liveData.setValue("someNewData")
liveData.setValue("againNewData")
 
// postValue
Thread() {
liveData.postValue("someNewData")
liveData.postValue("againNewData")
}.start

Здесь для разных потоков используются разные методы. Метод setValue вызывается два раза. Это значит, что экран обновится дважды, потому что код выполняется в основном потоке приложения. Метод postValue выполняется асинхронно, поэтому обновление экрана будет зависеть от работы основного потока. 

Иногда во время вызова метода liveData.postValue("someNewData") экран ещё не открыт или приложение свёрнуто. А во время выполнения метода liveData.postValue("againNewData") экран уже виден пользователю. Это значит, что на экране отобразятся только последние данные "againNewData"

При использовании postValue будьте внимательны. Если на эту LiveData никто не был подписан во время обновления данных, то вызов getValue их вам не вернёт. 

Надеемся, что эта статья помогла вам узнать немного больше об использовании LiveData, особенно в контексте асинхронной работы, которой так много в разработке под Android.

Этот материал — перевод статьи LiveData setValue vs postValue in Android.

программированиеразработка приложенийandroid
Нашли ошибку в тексте? Напишите нам.
Спасибо,
что читаете наш блог!