我正在使用Jetpack Compose构建一个Android应用程序,我想制作一个存储在数据存储首选项中的PIN码。我为它创建了以下数据源:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "mydocument")
val PIN_CODE_KEY = stringPreferencesKey("pin_code")
class PinCodeLocalDataSource @Inject constructor(
@ApplicationContext private val context: Context
) {
fun getPinCode(): Flow<List<Int>> {
Log.d(TAG, "Pin code status collected")
return context.dataStore.data.map { preferences ->
Log.d(TAG, "Data store mapped")
val pin: String = preferences[PIN_CODE_KEY] ?: ""
val intPin: List<Int> = pin.toCharArray().map {
it.digitToIntOrNull() ?: 0
}
intPin
}.catch { e ->
Log.e(TAG, "Caught an exception while reading pin: ${e.message}")
}
}
suspend fun setPinCode(newCode: List<Int>) {
context.dataStore.edit { mutablePreferences ->
mutablePreferences[PIN_CODE_KEY] = newCode.joinToString("") {
it.toString()
}
}
}
}
当查看logcat并启动我的应用程序时,它只显示“Pin code status collected”,但没有错误或任何表明它捕获了错误的内容。在错误时,我想发出一个错误状态,但没有catch{}就不能这样做。我做错了什么?
我尝试在下游捕获异常,但也没有成功。这是我的存储库方法的代码,它使用流构建器首先发出加载状态,然后它将流中的每个下一个值Map为状态:
fun load(): Flow<Loader<List<Int>>> = flow {
emit(Loader.Loading)
dataSource.getPinCode().onEach {
emit(Loader.Success(it))
}.catch { e ->
Log.d(TAG, "Loading pin code failed.")
if(e is IOException)
emit(Loader.Error)
else
throw e
}
}.flowOn(Dispatchers.IO)
1条答案
按热度按时间7gcisfzg1#
这真的很愚蠢,但唯一错的是我如何收集流量。
onEach{}
不是终端操作符,因此,正如cactustictacs正确假设的那样,流的主体永远不会运行。数据存储返回一个空值,如果它还没有被写入,所以我只是检查。新的repository方法:在这里,我使用flow builder和
emitAll
连接两个流