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

如何用Kotlin结合SQLite实现登录功能?代码崩溃求助

解决Kotlin+SQLite登录崩溃问题

嘿,我看了你的代码,登录按钮点击后崩溃的问题根源在SQL查询语句的语法错误,咱们一步步来修复它,顺便给你提一些优化建议:

问题分析

先看你登录按钮里的这段SQL代码:

val fila = bd.rawQuery( 
    "select nombre_usuario,clave1 from usuario where nombre_usuario=${et_02.text} && ${etp_03.text}"
    null
)

这里有3个致命问题:

  1. 字符串未加单引号:SQL中字符串类型的字段值必须用单引号包裹,你直接拼接et_02.text会让SQL把输入当成数据库标识符,触发语法错误导致崩溃。
  2. WHERE条件不完整:你只写了用户名和密码的变量,但没有关联对应的字段(比如密码应该和clave1字段对比),而且SQL里的逻辑与是AND,不是&&。
  3. SQL注入风险:直接拼接用户输入到SQL语句里,恶意用户可以通过输入特殊字符篡改SQL逻辑,窃取或破坏数据。

修复后的登录代码

我给你修正了登录按钮的逻辑,用参数化查询解决以上问题,还加了输入校验和资源释放:

bt_ingresar_04.setOnClickListener { 
    // 先获取并修剪输入内容,避免空格干扰
    val userName = et_02.text.toString().trim()
    val password = etp_03.text.toString().trim()

    // 校验输入是否为空
    if (userName.isEmpty() || password.isEmpty()) {
        Toast.makeText(this, "请填写用户名和密码", Toast.LENGTH_SHORT).show()
        return@setOnClickListener
    }

    val admin = AdminSQliteOpenHelper(this, "administracion", null, 1)
    // 查询操作使用readableDatabase即可,无需 writable
    val bd = admin.readableDatabase
    // 用?作为占位符,避免SQL注入和语法错误
    val fila = bd.rawQuery( 
        "select nombre_usuario,clave1 from usuario where nombre_usuario = ? AND clave1 = ?",
        arrayOf(userName, password) // 占位符对应的参数数组
    )

    if (fila.moveToFirst()) {
        Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show()
        val intent = Intent(this, MainActivity_03::class.java)
        startActivity(intent)
    } else {
        Toast.makeText(this, "Usuario no registrado", Toast.LENGTH_SHORT).show()
    }

    // 必须关闭游标和数据库连接,避免资源泄漏
    fila.close()
    bd.close()
}

额外优化建议

  1. 注册时校验两次密码一致性:
    你现在的注册代码没有检查两次输入的密码是否相同,用户输错也会注册成功,体验很差,加上这段逻辑:
    bt_204.setOnClickListener { 
        val userName = et_nombre_201.text.toString().trim()
        val pass1 = et_pasword_204.text.toString().trim()
        val pass2 = et_paword_203.text.toString().trim()
    
        // 校验输入和密码一致性
        if (userName.isEmpty() || pass1.isEmpty() || pass2.isEmpty()) {
            Toast.makeText(this,"请填写完整信息", Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }
        if (pass1 != pass2) {
            Toast.makeText(this,"两次输入的密码不一致", Toast.LENGTH_SHORT).show()
            return@setOnClickListener
        }
    
        // 后续的数据库插入代码...
    }
    
  2. 后台线程执行数据库操作:
    直接在UI线程操作数据库会导致界面卡顿,推荐用Kotlin协outines把数据库操作放到后台:
    // 先添加协程依赖(如果没加的话),然后用launch(Dispatchers.IO)执行
    bt_ingresar_04.setOnClickListener { 
        lifecycleScope.launch(Dispatchers.IO) {
            // 数据库操作逻辑...
            withContext(Dispatchers.Main) {
                // 更新UI(比如Toast、跳转页面)
            }
        }
    }
    
  3. 不要明文存储密码:
    现在你的代码直接把密码明文存到数据库,一旦数据库泄露,用户密码就会被盗。建议用哈希算法(比如SHA-256)加盐后存储密码,验证时再对输入的密码做同样的哈希处理后对比。

内容的提问来源于stack exchange,提问作者Jorge Leonardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:57:46