SharedPreference值比对异常:值相同却进入else分支?求解决方案
问题排查与解决
核心问题分析
- 空安全隐患:
sp是可空类型,若context为 null,sp?.getString(...)会返回 null,此时db_mail和db_pswd会是 null。而inp_mail_str是输入框 trim 后的非空字符串(即使输入为空,trim 后也是空字符串 ""),null 和空字符串用==比较结果为 false,直接导致正确分支无法触发。 - 无效分支判断:
else if(inp_mail_str == " ")完全无效——因为前面已经对inp_mail_str执行了trim(),处理后不可能等于单个空格,这个分支永远不会被执行。 - 隐性空白字符:虽然 Logcat 显示内容一致,但可能存在全角空格、特殊换行符这类看不见的隐性字符,
trim()只能去除半角空格、常规换行和制表符,这类特殊字符会导致比对失败。
修复后的代码
val inp_mail_str = inp_mail.text.trim() val inp_pswd_str = inp_pswd.text.trim() // 确保context非空,避免sp为null的情况 val sp = requireNotNull(context).getSharedPreferences("Registration Details", Context.MODE_PRIVATE) // 处理可空性,确保db_mail和db_pswd永远是非空字符串 val db_mail = sp.getString("Email", "")?.trim() ?: "" val db_pswd = sp.getString("Password", "")?.trim() ?: "" // 优先判断输入为空的情况 if (inp_mail_str.isEmpty() || inp_pswd_str.isEmpty()) { Toast.makeText(context, "请输入用户名和密码", Toast.LENGTH_SHORT).show() } else if (inp_mail_str == db_mail && inp_pswd_str == db_pswd) { Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show() } else { // 打印详细比对信息,方便排查隐性问题 Log.d("LoginCheck", "输入邮箱: '$inp_mail_str' | 存储邮箱: '$db_mail'") Log.d("LoginCheck", "输入密码: '$inp_pswd_str' | 存储密码: '$db_pswd'") Toast.makeText(context, "登录失败", Toast.LENGTH_SHORT).show() }
额外排查建议
- 打印字符串长度:比对前输出
inp_mail_str.length和db_mail.length,若长度不一致,说明存在隐性字符。 - 清理测试数据:测试前清除App存储数据,重新注册后再登录,避免旧数据干扰。
内容的提问来源于stack exchange,提问作者Anandhu
相关产品推荐
相关产品推荐

