You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从内部存储读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:05:42