StateFlow, der Daten aus der Room-Datenbank Dao erhält und in das Ansichtsmodell einfügt, wird nach dao.insertAll() nichAndroid

Forum für diejenigen, die für Android programmieren
Anonymous
 StateFlow, der Daten aus der Room-Datenbank Dao erhält und in das Ansichtsmodell einfügt, wird nach dao.insertAll() nich

Post by Anonymous »

In meinem Android Jetpack Compose-Projekt mit Room-Datenbank ist das ViewModel ein in den Griff eingefügtes Dao und verfügt über eine Eigenschaft vom Typ StateFlow, deren Wert das Ergebnis des Aufrufs von dao.getAll() ist. Ich habe versucht, meine Datenbankentität mithilfe einer ViewModel-Funktion vorab zu füllen, die dao.insertAll() aufruft und diese Funktion aus einem Compose-Layout heraus aufruft. Die Funktion dao.insertAll() gibt erfolgreich eine Liste von Entitäts-IDs zurück, aber die entsprechende ViewModel-Eigenschaft vom Typ StateFlow wird nicht aktualisiert.
Mein ViewModel (teilweise)

Code: Select all

@HiltViewModel
class CalendarViewModel @Inject constructor(private val scheduleDao : ScheduleDao) : ViewModel() {
val schedule : StateFlow = scheduleDao.getAll().stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = emptyList()
)
private fun getScheduleEntities() : List {
val scheduleEntities = mutableListOf()
try {
val startDate = LocalDate(2000, 1, 1)
val endDate = java.time.LocalDate.now().toKotlinLocalDate()
val startTime = java.time.LocalTime.of(9, 0, 0)
val endTime = java.time.LocalTime.of(18, 0, 0)
val timeList = generateSequence(startTime) { it.plusMinutes(30) }.takeWhile { it  item.format(timeFormat) }
}
@TypeConverter
fun stringToListLocalTime(value : String?) : List? {
return value?.split(',')?.map { item ->  LocalTime.parse(item.trim(), timeFormat) }
}
}
Dao:

Code: Select all

@Dao
interface ScheduleDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOne(vararg scheduleEntity : ScheduleEntity)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(scheduleEntities : List): List

@Delete
suspend fun delete(scheduleEntity : ScheduleEntity)

@Query("SELECT * FROM ScheduleEntity")
fun getAll() : Flow
}
Raumdatenbank und Hilt-Modul

Code: Select all

@Database(entities = [ScheduleEntity::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class CalendarDatabase : RoomDatabase() {
abstract fun scheduleDao() : ScheduleDao
companion object {
var INSTANCE : CalendarDatabase? = null
fun getDatabase(context: Context) : CalendarDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(context.applicationContext, CalendarDatabase::class.java, "tasks")
.enableMultiInstanceInvalidation()
.build()
INSTANCE = instance
return instance
}
}
}
}

@Module
@InstallIn(SingletonComponent::class)
object TasksModule {
@Provides
@Singleton
fun provideApplicationScope(): CoroutineScope {
return CoroutineScope(SupervisorJob() + Dispatchers.IO)
}
@Provides
@Singleton
fun provideDatabase(
@ApplicationContext context: Context) : CalendarDatabase = CalendarDatabase.getDatabase(context)
@Provides
@Singleton
fun provideScheduleDao(calendarDatabase : CalendarDatabase) : ScheduleDao = calendarDatabase.scheduleDao()
}
Mein Compose-Layout (teilweise)

Code: Select all

@Composable
fun MainLayout(modifier: Modifier? = null, viewModel : CalendarViewModel = hiltViewModel()) {
val schedule by viewModel.schedule.collectAsStateWithLifecycle()
viewModel.fillScheduleEntities()
}
Ich habe auch versucht, restartTrigger zu verwenden:

Code: Select all

private val refreshTrigger = MutableSharedFlow(replay = 1).apply { tryEmit(Unit) }
val schedule : StateFlow = refreshTrigger.flatMapLatest { scheduleDao.getAll() }.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = emptyList()
)
...
scheduleEntities = getScheduleEntities()
val scheduleIds = scheduleDao.insertAll(scheduleEntities)
refreshTrigger.emit(Unit)
Aber es hat nicht geholfen. Wie kann ich dieses Problem lösen?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post