Kotlin,ViewModel 中的 DataStore 流值始终为 null

Kotlin, DataStore flow values in ViewModel are always null

我无法理解为什么来自 Datastore 的流的 expiryDate 值始终为空。 checkExpiry() 用于确定导航路线,仅在viewmodel中使用(活动片段中没有观察者)。

如有任何帮助,我们将不胜感激。

视图模型

@HiltViewModel
class MyViewModel
@Inject
constructor(
    private val userPreferences: UserPreferences,
    private val savedSate: SavedStateHandle
) : ViewModel() {

    private val expiryTimestamp = userPreferences.expiryTimestampFlow.asLiveData()

    private fun checkExpiry(): Boolean {
        val calendar = Calendar.getInstance()
        return (calendar.timeInMillis > expiryTimestamp.value!!)
   } 

数据存储

@Singleton
class UserPreferences
@Inject
constructor(@ApplicationContext context: Context) {

    private val Context.dataStore by preferencesDataStore("user_preferences")
    private val dataStore = context.dataStore

    //Preferences keys
    private object PreferencesKeys {
        val EXPIRY_TIMESTAMP = longPreferencesKey("expiryTimeStamp")
    }

    //Get Functions
    val expiryTimestampFlow = dataStore.data
        .catch { exception ->
            if (exception is IOException) {
                Log.e(TAG, "Error reading expiry date", exception)
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }
        .map { preferences ->
            preferences[PreferencesKeys.EXPIRY_TIMESTAMP] ?: 1672491600000
        }

您的 ViewModel 中的 LiveData 未激活。您可以这样激活它:

private val expiryTimestamp = userPreferences.expiryTimestampFlow.asLiveData(viewModelScope.coroutineContext)

编辑:

如果您在来自 DataStore 的流尚未发出值时调用 checkExpiry() 函数(因为它必须执行一些 IO),您可以在 LiveData 中获取 null。

由于您没有从 activity 或片段中观察到此值,因此不需要 LiveData。您可以像这样查询 DataStore:

private suspend fun checkExpiry(): Boolean {
    val calendar = Calendar.getInstance()
    return (calendar.timeInMillis > userPreferences.expiryTimestampFlow.first())
}