从内部存储读取List时出现类型不匹配问题求助
类型不匹配问题修复与Todo存储方案优化
一、修复类型不匹配错误
你的代码核心问题是files?.filter(...)?.map { ... }的返回值类型不匹配:map会把每个文件处理后返回的todoItemList收集成List<MutableList<Todo>>,但函数声明返回的是List<Todo>,这就导致了类型冲突。而且你本来就是要把所有文件的Todo项合并到同一个列表里,不需要用map,改用forEach遍历处理每个文件即可,同时还要修复原代码中存在的数组越界风险:
修改后的代码:
private suspend fun loadTodoItemsFromInternalStorage(): List<Todo> { return withContext(Dispatchers.IO) { val todoItemList: MutableList<Todo> = mutableListOf() val files = filesDir.listFiles() files?.filter { it.canRead() && it.isFile && it.name.endsWith(".txt") }?.forEach { file -> val lines = file.bufferedReader().readLines() // 按步长2遍历,避免i+1越界 for (i in lines.indices step 2) { if (i + 1 < lines.size) { val title = lines[i] val isCompleted = lines[i+1].toBoolean() todoItemList.add(Todo(title, isCompleted)) } } } todoItemList } }
二、更优的Todo存储方案
你当前两行存一个Todo的方案容错性差(比如文件损坏、行数不对都会导致解析失败),推荐以下几种更可靠的方案:
1. 单文件JSON序列化
把整个List<Todo>序列化为JSON字符串,存到一个单独文件中,读写逻辑更简洁:
- 用官方推荐的
kotlinx.serialization实现:
先给Todo类添加序列化注解:
保存函数:@Serializable data class Todo(val title: String, val isCompleted: Boolean)
加载函数:private suspend fun saveTodoItemsToInternalStorage(todos: List<Todo>) { withContext(Dispatchers.IO) { val json = Json.encodeToString(todos) openFileOutput("todos.json", Context.MODE_PRIVATE).use { it.write(json.toByteArray()) } } }private suspend fun loadTodoItemsFromInternalStorage(): List<Todo> { return withContext(Dispatchers.IO) { return@withContext try { val json = openFileInput("todos.json").bufferedReader().readText() Json.decodeFromString<List<Todo>>(json) } catch (e: Exception) { emptyList() } } }
2. Room数据库
如果Todo项数量较多,或者需要查询、排序、实时更新等操作,Room是最佳选择——它是Android官方ORM框架,支持数据观察、事务处理等功能,能大幅简化本地数据管理逻辑。
3. SharedPreferences(适合少量数据)
如果Todo项数量极少(比如十几个以内),可以用SharedPreferences存储JSON格式的字符串,操作逻辑和单文件JSON类似,但更适合存储小体量的键值对数据。
内容的提问来源于stack exchange,提问作者Bennet Müller
相关产品推荐
相关产品推荐

