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

Kotlin实现Android SQLite数据保存闪退排查及API31咨询

崩溃根因

从Logcat捕获的报错日志可以直接定位问题,和数据库操作逻辑本身没有直接关系:

Caused by: java.lang.NullPointerException: findViewById(R.id.buttonsave) must not be null

你在MainActivity的onCreate生命周期方法中,代码执行顺序完全错误:在调用setContentView(R.layout.activity_main)加载布局文件之前,就提前执行了buttonsave.setOnClickListener的控件绑定逻辑。此时布局还未挂载到Activity上,系统找不到对应ID的控件,直接触发空指针闪退。
额外注意:从你的菜单跳转逻辑看,点击新建笔记会跳转到addnoteactivity,如果buttonsave、editTextTitle、editTextdesc这三个控件是写在addnoteactivity对应的布局文件里,你把这部分保存逻辑写在MainActivity中,就算调整了顺序也会找不到控件报空指针,这部分逻辑需要写在addnoteactivity的代码中。

修复方案

1. 调整Activity代码执行顺序

所有控件查找、事件绑定、RecyclerView初始化逻辑,必须放在setContentView()调用之后执行。如果保存逻辑属于新建笔记页面,就把对应代码移到addnoteactivity中。
修正后的MainActivity onCreate示例:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 必须第一时间加载布局,之后再操作控件
    setContentView(R.layout.activity_main)
    
    // 注意:如果buttonsave不在activity_main布局里,下面这段点击事件要移到addnoteactivity里
    buttonsave.setOnClickListener {
        val dbManger= DBmanager(this)
        val values = ContentValues()
        values.put("Title",editTextTitle.text.toString())
        values.put("Desc",editTextdesc.text.toString())
        val insertId= dbManger.Insert(values)
        if (insertId > 0 ){
            Toast.makeText(this, "یــادادشــت جـــدیِـد ذخـیره شـــد!", Toast.LENGTH_SHORT).show()
        } else{
            Toast.makeText(this, " خطــا در ذخـیره یــادادشــت !", Toast.LENGTH_SHORT).show()
        }
    }

    layoutManger = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
    adapter = Adapter()
    val list = ArrayList<Model>()
    list.apply {
        add(Model("fatemeh", "chamani fard"))
        add(Model("reyhaneh", "chamani fard"))
        add(Model("bahareh", "chamani fard"))
        add(Model("abolfazl", "chamani fard"))
    }
    adapter.setList(list)
    list_main.layoutManager=layoutManger
    list_main.adapter=adapter
}

2. 修复数据库类的潜在问题

你写的DBmanager类还有几个会触发异常的隐患,需要同步修改:

  • 类定义开头多打了冗余字符h,把hclass DBmanager改成class DBmanager
  • 建表语句的ID列添加自增属性,避免插入数据时不传ID导致报错,修改建表SQL为:
val sqlCreateTable="CREATE TABLE IF NOT EXISTS " + dbTable + " ("+ colID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+ colTitle +" TEXT,"+ colDesc +" TEXT);"
  • 删除DatabaseHelper的onCreate方法里弹Toast的代码:SQLiteOpenHelper的生命周期方法默认在工作线程执行,直接弹Toast会触发线程异常,数据库创建成功不需要额外给用户弹提示。
  • 类名、变量名建议遵循Kotlin驼峰命名规范,比如DBmanager改成DBManager,避免拼写错误导致的引用问题。
Android API 31 说明
  • API 31是Android系统的API级别编号,对应正式发布的Android 12版本,2021年10月由Google正式推送
  • 如果应用将targetSdkVersion设置为31,必须适配Android 12的系统行为变更要求,比如:所有带intent-filter的四大组件必须显式声明android:exported属性、申请精确闹钟权限、适配通知运行时权限等,否则应用在Android 12设备上会出现安装失败、运行崩溃的问题。

内容的提问来源于stack exchange,提问作者F.chamani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:48:21