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

SharedPreference值比对异常:值相同却进入else分支?求解决方案

问题排查与解决

核心问题分析

  1. 空安全隐患:sp 是可空类型,若 context 为 null,sp?.getString(...) 会返回 null,此时 db_mail 和 db_pswd 会是 null。而 inp_mail_str 是输入框 trim 后的非空字符串(即使输入为空,trim 后也是空字符串 ""),null 和空字符串用 == 比较结果为 false,直接导致正确分支无法触发。
  2. 无效分支判断:else if(inp_mail_str == " ") 完全无效——因为前面已经对 inp_mail_str 执行了 trim(),处理后不可能等于单个空格,这个分支永远不会被执行。
  3. 隐性空白字符:虽然 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:25:38