Почему невозможно получить новейшие данные с помощью метода .collectAsState()?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Почему невозможно получить новейшие данные с помощью метода .collectAsState()?

Сообщение Anonymous »

проблема
Невозможно получить новые данные в методе .collectAsState(), появилась в
кодеВ LoadFoodItemInfo.kt
Метод вызывается.

Код: Выделить всё

FoodItemRepository.setDatas(queriedFoodItemVOs)
Но после приведенного выше утверждения
выход

Код: Выделить всё

Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")
это

Код: Выделить всё

LaunchedEffect(Unit) block was called.foodItemVOs:[]
где
переменная foodItemVOs определяется следующим образом.

Код: Выделить всё

val foodItemVOs by foodItemViewModel.data.collectAsState()
Почему не удается получить новейшие данные с помощью метода CollectAsState в StateFlow?
Вот мой код. >
В LoadFoodItemInfo.kt

Код: Выделить всё

@Composable
fun LoadFoodItemInfo(
context:Context,
foodItemViewModel: FoodItemViewModel = viewModel(),
foodViewModel: FoodViewModel = viewModel(),
){
val TAG = "tag_LoadFoodItemInfo"
val selectedFoodItemVO by foodItemViewModel.selectedData.collectAsState()
val foodItemVOs by foodItemViewModel.data.collectAsState()
LaunchedEffect(Unit) {
Log.e(TAG,"-".repeat(50))
Log.e(TAG,"In LoadFoodItemInfo function, selectedFoodItemVO:${selectedFoodItemVO}")
val queriedFoodItemVOs = foodItemViewModel.selectFoodItemByDiaryIdAndMealCategoryId(selectedFoodItemVO)
Log.e(TAG,"In LoadFoodItemInfo function, queriedFoodItemVOs:${queriedFoodItemVOs}")
if(queriedFoodItemVOs.isEmpty()){                Toast.makeText(context,context.getString(R.string.load_food_item_info_failed), Toast.LENGTH_LONG)
.show()
return@LaunchedEffect
}
// set all elem of the array into repo -- FoodItemRepository.
FoodItemRepository.setDatas(queriedFoodItemVOs)            Toast.makeText(context,context.getString(R.string.load_food_item_info_successfully), Toast.LENGTH_LONG)
.show()
Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")
UpdateSelectedFoodItemVOs(
context = context,
foodItemVOs = foodItemVOs,
foodViewModel = foodViewModel,
)
Log.e(TAG,"-".repeat(50))
}
}
В FoodItemViewModel.kt

Код: Выделить всё

class FoodItemViewModel:ViewModel() {
private val repository = FoodItemRepository
val data: StateFlow[*]> = repository.datasFlow
...
}
В FoodItemRepository.kt

Код: Выделить всё

object FoodItemRepository {
val TAG = "tag_MealsOptionRepository"
private val _datasFlow: MutableStateFlow = MutableStateFlow(mutableListOf())
val datasFlow = _datasFlow.asStateFlow()
...
fun setDatas(newDatas: List) {
Log.e(TAG, "~".repeat(50))
Log.e(TAG, "In setDatas method,newDatas:${newDatas}")
_datasFlow.value = newDatas.toMutableList()
Log.e(TAG, "In setDatas method,_datasFlow.value:${_datasFlow.value}")
Log.e(TAG, "~".repeat(50))
}
...
}
Вот последняя часть содержимого Logcat, когда я запускал программу.

Код: Выделить всё

2024-11-10 21:52:43.992 26480-26480 tag\_sendHttpRequest com.example.healthhelper E sendHttpRequest function was finished called.

2024-11-10 21:52:43.992 26480-26480 tag\_sendHttpRequest com.example.healthhelper E --------------------------------------------------

2024-11-10 21:52:43.993 26480-26480 tag\_LoadFoodItemInfo com.example.healthhelper E In LoadFoodItemInfo function, queriedFoodItemVOs:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.993 26480-26480 tag\_MealsO...Repository com.example.healthhelper E ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E In setDatas method,newDatas:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E In setDatas method,\_datasFlow.value:\[FoodItemVO(diaryID=8, foodID=1001, mealCategoryID=3, grams=100.0)\]

2024-11-10 21:52:43.995 26480-26480 tag\_MealsO...Repository com.example.healthhelper E ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2024-11-10 21:52:43.998 26480-26480 tag\_LoadFoodItemInfo com.example.healthhelper E LaunchedEffect(Unit) block was called.foodItemVOs:\[\]

2024-11-10 21:52:43.999 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, foodItemVOs:\[\]

2024-11-10 21:52:44.000 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, foodNames:\[\]

2024-11-10 21:52:44.000 26480-26480 tag\_Update...oodItemVOs com.example.healthhelper E In UpdateSelectedFoodItemVOs function, selectedFoodItemVOs:\[\]
Признательность
Будем очень признательны за любые ответы или советы по этой проблеме.
Что я пробовал ?
  • Найдите подробную информацию о проблеме с помощью вывода в Logcat.
  • прочитайте, что Jetpack Compose CollectAsState() не работает с Flow join() и попытайтесь понять использование в этой статье.
Чего я ожидал?
Получить новейшие данные из репозитория в любое время (в том числе после обновления значения StateFlow) в репозитории.
P.S.
Я следую шаблону проектирования MVVM.
Расположение проекта
Проект находится на Github.

Код: Выделить всё

https://github.com/junshin4211/HealthHelper/blob/2b9fd8d89bd7a9bb3ee5387d8ebfc9f2e578fbbb/app
Но обратите внимание, что версия этой версии контролируется Git, поэтому другие люди, не входящие в эту группу, могут не иметь разрешения на доступ к ней.

1-е редактирование
предисловие
Я воспользовался комментарием @tyg, чтобы попытаться воспроизвести минимальный пример. Также я переформатирую код. И измените описание этой проблемы.
проблема
то же, что и выше.
описание
В LoadFoodItemInfo.kt
Метод вызывается следующим образом.

Код: Выделить всё

FoodItemRepository.setDatas(queriedFoodItemVOs)
Но после выполнения приведенного выше оператора
вывод

Код: Выделить всё

Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")
это

Код: Выделить всё

LaunchedEffect(Unit) block was called.foodItemVOs:[]
Logcat
Вывод Logcat
Код

[code]LoadFoodItemInfoTest1.kt[/code]

Вот определение функции LoadFoodItemInfoTest1.

Код: Выделить всё

@Composable
fun LoadFoodItemInfoTest1(
context:Context,
foodItemViewModel: FoodItemViewModel = viewModel(),
){
val TAG = "tag_LoadFoodItemInfoTest1"

val selectedFoodItemVO by foodItemViewModel.selectedData.collectAsState()
val foodItemVOs by foodItemViewModel.data.collectAsState()

LaunchedEffect(Unit) {
Log.e(TAG,"-".repeat(50))
Log.e(TAG,"In LoadFoodItemInfo function, selectedFoodItemVO:${selectedFoodItemVO}")
val queriedFoodItemVOs =  foodItemViewModel.selectFoodItemByDiaryIdAndMealCategoryId(selectedFoodItemVO)
Log.e(TAG,"In LoadFoodItemInfo function, queriedFoodItemVOs:${queriedFoodItemVOs}")
if(queriedFoodItemVOs.isEmpty()){
return@LaunchedEffect
}
Log.e(TAG,"The statement is ready to execute FoodItemRepository.setDatas(queriedFoodItemVOs).")
FoodItemRepository.setDatas(queriedFoodItemVOs)
Log.e(TAG,"LaunchedEffect(Unit) block was called.foodItemVOs:${foodItemVOs}")
Log.e(TAG,"-".repeat(50))
}
}

[code]FoodItemViewModel.kt[/code]

Вот часть кода определения класса FoodItemViewModel (который является моделью представления для объекта FoodItemRepository).

Код: Выделить всё

// some import statements

class FoodItemViewModel:ViewModel() {
private val repository = FoodItemRepository
val data: StateFlow = repository.datasFlow
...
suspend fun selectFoodItemByDiaryIdAndMealCategoryId(
foodItemVO: FoodItemVO,
):List{
val url = DietDiaryUrl.selectFoodItemByDiaryIdAndMealCategoryIdUrl
return try {
val result = httpPost(url, gson.toJson(foodItemVO))
val collectionType = object : TypeToken() {}.type
gson.fromJson(result, collectionType) ?: emptyList()
} catch (e: Exception) {
Log.e("Fetch Error", "Error fetching food from ${url}: ${e.message}", e)
emptyList()
}
}
...
Вот несколько операторов импорта в FoodItemViewModel.kt

Код: Выделить всё

import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.flow.StateFlow
import com.example.healthhelper.dietary.gson.gson
import androidx.lifecycle.ViewModel
где

Код: Выделить всё

DietDiaryUrl.selectFoodItemByDiaryIdAndMealCategoryIdUrl
определяется в DietDiaryUrl.kt следующим образом.

Код: Выделить всё

val selectFoodItemByDiaryIdAndMealCategoryIdUrl: String
get() = "${serverUrl}/dietDiary/foodItem/selectFoodItemByDiaryIdAndMealCategoryId"

В FoodItemRepository.kt

Часть кода объекта FoodItemRepository показана следующим образом.

Код: Выделить всё

// some import statements
object FoodItemRepository {
val TAG = "tag_MealsOptionRepository"

private val _datasFlow: MutableStateFlow  = MutableStateFlow(mutableListOf())
val datasFlow: StateFlow
get() = _datasFlow.asStateFlow()
...

fun setDatas(newDatas:List){
Log.e(TAG,"~".repeat(50))
Log.e(TAG,"In setDatas method,newDatas:${newDatas}")
_datasFlow.value = newDatas.toMutableList()
Log.e(TAG,"In setDatas method,_datasFlow.value:${_datasFlow.value}")
Log.e(TAG,"~".repeat(50))
}

...
Вот несколько операторов импорта в FoodItemRepository.kt

Код: Выделить всё

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
2-е редактирование
описание
Я меняю его с MutableStateFlow< MutableList> в ``MutableStateFlow`, как показано ниже.

Код: Выделить всё

object FoodItemRepository {
val TAG = "tag_MealsOptionRepository"

private val _datasFlow: MutableStateFlow = MutableStateFlow(listOf())
val datasFlow: StateFlow
get() = _datasFlow.asStateFlow()
Но у меня это не работает.
Вывод Logcat
Вывод Логарифмический анализ

Подробнее здесь: https://stackoverflow.com/questions/791 ... ate-method
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Почему невозможно получить новейшие данные с помощью метода .collectAsState()?
    Anonymous » » в форуме Android
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • (Flutter) HTTP-запрос не отвечает на новейшие устройства Android
    Anonymous » » в форуме Android
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • (Flutter) HTTP-запрос не отвечает на новейшие устройства Android
    Anonymous » » в форуме Android
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • (Flutter) HTTP-запрос не отвечает на новейшие устройства Android
    Anonymous » » в форуме Android
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Лучший способ использовать CollectAsState в приложении KMM с архитектурой ViewModel
    Anonymous » » в форуме Android
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Android»