Должен ли я использовать LiveData для чтения запроса из базы данных комнаты в Android - Kotlin

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

У меня есть эти файлы:

  • Database (2 таблицы: покупаемый товар и ссылочный товар) + DAO (уникальный)
  • Repository (Уникальный)
  • ViewModel (Уникальный)
  • Fragment/Activity

В DAO я определяю все свои запросы. В настоящее время все мои //Custom запросы возвращают такой LiveData<> тип:

@Dao
interface ShoppingDao {

    // Shopping Items
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertShoppingItem(item: ShoppingItem)

    @Delete
    suspend fun deleteShoppingItem(item: ShoppingItem)

    @Update
    suspend fun updateShoppingItem(item: ShoppingItem)

    @Query(value = "DELETE FROM shopping_items")
    suspend fun deleteAllShoppingItems()

    @Query(value = "SELECT * FROM shopping_items")
    fun getAllShoppingItem(): LiveData<List<ShoppingItem>>

    // Custom
    @Query(value = "SELECT COALESCE(SUM(item_amount),0) FROM shopping_items")
    fun getAllShoppingCount(): LiveData<Int>

    @Query(value = "SELECT COALESCE(SUM(item_total_price), 0.0) FROM shopping_items")
    fun getAllShoppingTotal(): LiveData<Float>

Тогда в репозитории ни один из них не использует suspend fun для вызова. Таким образом, в ViewModel они также не используют suspend fun для вызова.

Я хотел бы использовать, например, getAllShoppingCount() без использования LiveData с Observer.

Является ли это возможным ?

Это лучшая практика?

Без LiveData мне придется использовать suspend fun для выполнения моих Query, но когда я использую:

fun updateShoppingItem(item: ShoppingItem) = CoroutineScope(Dispatchers.Main).launch {
    repository.updateShoppingItem(item)
}

Он возвращает Job, а не тот тип, который Query должен возвращать. Как я могу это изменить, если я могу использовать что-то еще, кроме LiveData.


person Francky380    schedule 07.05.2020    source источник
comment
он должен помочь вам: stackoverflow.com/questions/55484682/   -  person Hosein Haqiqian    schedule 08.05.2020
comment
Спасибо, но не полагаюсь ответить на все вопросы. Я читал это раньше, но там просто сказано, что Дао не должен возвращать LiveData ‹› an после этого?   -  person Francky380    schedule 08.05.2020
comment
вы не можете получить доступ к базе данных в основном потоке, поэтому сначала вам нужно использовать Dispatcher.IO, а затем использовать приостановку перед функцией dao и установить для нее тип возвращаемого значения   -  person Hosein Haqiqian    schedule 08.05.2020


Ответы (1)


Мои мысли:

  1. Нет ограничения «вы должны использовать LiveData в комнате». Есть «вы можете использовать LiveData» (ссылка на документацию). Также вы можете использовать другие методы, реализующие шаблон Observer - RxJava, поток сопрограмм . Вы можете использовать один из этих механизмов для достижения реактивного потока в ваших данных - что-то меняется в локальной БД, ваш фрагмент / действие мгновенно заметит это изменение.
  2. Нет ограничения «вы не должны использовать LiveData в комнате». В упомянутой статье был просто ответ - «Если вы не хотите использовать LiveData - ну, не стоит». Может быть, есть тенденция к замене LiveData в Kotlin на Coroutines Flow, но сейчас это не требует.
  3. Вы также можете использовать асинхронные сопрограммы. В этом случае вы не заметите изменений в своей базе данных. В вашей модели viewModel вам проще вызвать функцию приостановки с помощью расширения KTX

    viewModelScope.launch(Dispatchers.IO) { repository.updateShoppingItem(item) }

  4. Но что именно использовать, слишком много «вы можете использовать это» и «вы можете использовать то»? Ну, как обычно - смотря по обстоятельствам, и единого best-метода нет, а «если» очень много. Если вам не нужно наблюдать за изменениями в ваших данных в режиме онлайн, вы используете Kotlin и знакомы с сопрограммами - вы можете их использовать. Если вы используете Java в этом случае, и вы не знакомы с RxJava и не хотите его изучать (все же почему?), Вам придется вручную переместить весь ваш код, работающий с db, в другой поток. Если вы поклонник RxJava - вы можете использовать его, даже если используете Kotlin. Если вы поклонник RxJava, но хотите быть в курсе тенденций - вы можете использовать Flow.

Надеюсь, это поможет.

person sergiy tikhonov    schedule 08.05.2020