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

Room数据库插入功能异常:Kotlin代码排查与修正需求

代码语法问题及修复方案

先明确你代码里的几个核心错误:

1. View Binding 使用错误

你通过ActivityAddRecipeBinding初始化了绑定对象,但setContentView仍用传统布局资源ID,导致绑定无法关联布局控件,点击事件可能失效。

2. DAO 调用方式错误

Dao.insertRecipe(recipe)是直接调用接口的静态方法,但Room的DAO是通过数据库实例生成的实现类,必须用你初始化的daoObject实例来调用插入方法。

3. 冗余与拼写问题

  • 导入了无用的ActivityLoginBinding,可直接删除;
  • 若Recipe实体类字段是title,你代码里写的tittle是拼写错误,会导致字段映射失败。

4. 数据库操作规范问题

你已经用协程在IO线程执行数据库操作,allowMainThreadQueries配置可以移除,避免后续主线程操作数据库引发ANR。


修改后的完整代码

package com.example.recipeapp

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.room.Room
import com.example.recipeapp.databinding.ActivityAddRecipeBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class AddRecipeActivity: AppCompatActivity() {

    private val binding: ActivityAddRecipeBinding by lazy{
        ActivityAddRecipeBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 改用binding.root作为布局内容
        setContentView(binding.root)
        
        // 移除allowMainThreadQueries,协程已在IO线程处理操作
        val db = Room.databaseBuilder(this@AddRecipeActivity, AppDatabase::class.java, "db_name")
            .fallbackToDestructiveMigration()
            .createFromAsset("recipe.db")
            .build()

        val daoObject: Dao = db.getDao()

        binding.addRecipe.setOnClickListener {
            val link = binding.recipeLink.text.toString()
            val recipeName = binding.recipename.text.toString()
            val recipeIng = binding.recipeIng1.text.toString()
            val recipeSteps = binding.recipeDes1.text.toString()
            val cat= binding.recipeCat1.text.toString()

            // 可选:添加输入非空校验,避免插入无效数据
            if (recipeName.isBlank() || recipeIng.isBlank()) {
                // 这里可添加Toast提示用户补全必填项
                return@setOnClickListener
            }

            CoroutineScope(Dispatchers.IO).launch {
                // 传入dao实例执行插入
                addRecipe(daoObject, link, recipeName, recipeIng, recipeSteps, cat)
                withContext(Dispatchers.Main) {
                    startActivity(Intent(this@AddRecipeActivity, HomeActivity::class.java))
                    // 结束当前页面,避免返回时重复触发插入
                    finish()
                }
            }
        }
    }

    // 新增dao参数,用实例调用插入方法
    private fun addRecipe(dao: Dao, link: String, recipeName: String, recipeIng: String, recipeSteps: String, cat: String) {
        val recipe = Recipe(
            img = link,
            // 注意:匹配Recipe实体类的字段名,这里修正拼写为title
            title = recipeName,
            des = recipeSteps,
            ing = recipeIng,
            category = cat
        )
        // 使用dao实例执行插入
        dao.insertRecipe(recipe)
    }
}

额外注意事项

  1. 实体类字段匹配:确保Recipe实体类的字段名和构造参数完全一致,否则Room无法完成字段映射。
  2. 协程作用域优化:建议用viewModelScope替代直接创建CoroutineScope,避免页面销毁后协程仍运行导致内存泄漏,需依赖androidx.lifecycle:lifecycle-viewmodel-ktx库。
  3. 数据库迁移:fallbackToDestructiveMigration会在数据库结构变化时清空数据,正式环境建议编写迁移脚本。

内容的提问来源于stack exchange,提问作者Shreya Deshingkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:00:05