如何用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个致命问题:
- 字符串未加单引号:SQL中字符串类型的字段值必须用单引号包裹,你直接拼接
et_02.text会让SQL把输入当成数据库标识符,触发语法错误导致崩溃。 - WHERE条件不完整:你只写了用户名和密码的变量,但没有关联对应的字段(比如密码应该和
clave1字段对比),而且SQL里的逻辑与是AND,不是&&。 - 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() }
额外优化建议
- 注册时校验两次密码一致性:
你现在的注册代码没有检查两次输入的密码是否相同,用户输错也会注册成功,体验很差,加上这段逻辑: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 } // 后续的数据库插入代码... } - 后台线程执行数据库操作:
直接在UI线程操作数据库会导致界面卡顿,推荐用Kotlin协outines把数据库操作放到后台:// 先添加协程依赖(如果没加的话),然后用launch(Dispatchers.IO)执行 bt_ingresar_04.setOnClickListener { lifecycleScope.launch(Dispatchers.IO) { // 数据库操作逻辑... withContext(Dispatchers.Main) { // 更新UI(比如Toast、跳转页面) } } } - 不要明文存储密码:
现在你的代码直接把密码明文存到数据库,一旦数据库泄露,用户密码就会被盗。建议用哈希算法(比如SHA-256)加盐后存储密码,验证时再对输入的密码做同样的哈希处理后对比。
内容的提问来源于stack exchange,提问作者Jorge Leonardo
相关产品推荐
相关产品推荐

