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

Android应用登录模块Java If/Else语句执行异常崩溃问题求助

问题排查:输入错误账号密码时应用崩溃的原因及修复方案

我一眼就看出问题所在了——空指针异常(NullPointerException)!当你输入不存在的用户名时,readUser方法会返回null,但你在MainActivity里直接调用u.getUser()和u.getPass(),这就相当于在操作一个不存在的对象,直接导致应用崩溃,根本走不到else分支的Toast提示。

具体问题分析

  1. 在DBHelper的readUser方法中:如果查询不到匹配的用户,变量u会保持初始值null并返回。
  2. 在MainActivity的登录点击事件里:你没有判断u是否为null,直接调用u.getUser().equals(username),这一步就会触发空指针,直接导致崩溃。

修复方案

第一步:修改MainActivity的登录逻辑,先判空再验证

btnLogin.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
        String username = txtUser.getText().toString(); 
        String pass = txtPassword.getText().toString(); 
        User u = myDB.readUser(username); 
        // 先确认用户存在,再验证用户名和密码
        if(u != null && username.equals(u.getUser()) && pass.equals(u.getPass())){ 
            Intent menu = new Intent(getApplicationContext(), MainMenu.class); 
            startActivity(menu); 
        } else { 
            Toast.makeText(MainActivity.this, "Incorrect username or password!", Toast.LENGTH_SHORT).show(); 
        } 
    } 
}); 

这里做了两个关键优化:

  • 先判断u != null,确保查询到了用户再进行后续操作
  • 把u.getUser().equals(username)改成username.equals(u.getUser()),这种写法更安全,即使u.getUser()意外为null也不会触发空指针

第二步:优化DBHelper的readUser方法,避免资源泄漏并便于排查问题

原来的方法里有几个小问题:没判断cursor是否为null、异常被吞掉了、还没关闭cursor。修改后:

public User readUser(String user){ 
    SQLiteDatabase db = this.getReadableDatabase(); 
    User u = null; 
    Cursor cursor = null;
    String where = col_uname + " = ?"; 
    String[] selectionArgs = {user}; 

    try { 
        cursor = db.query("tblUser", null, where, selectionArgs, null, null, null); 
        if(cursor != null && cursor.moveToNext()) { 
            u = new User(); 
            u.setUser(cursor.getString(0)); 
            u.setPass(cursor.getString(4)); 
            u.setFname(cursor.getString(1)); 
            u.setMname(cursor.getString(2)); 
            u.setLname(cursor.getString(3)); 
            u.setMobile(cursor.getString(6)); 
            u.setCity(cursor.getString(5)); 
        } 
    } catch(Exception ex) {
        // 打印异常日志,方便后续排查其他问题
        ex.printStackTrace(); 
    } finally {
        // 确保cursor和数据库都被关闭,避免资源泄漏
        if(cursor != null){
            cursor.close();
        }
        db.close(); 
    }
    return u; 
}

这里的改进点:

  • 把cursor声明在try外面,确保在finally里能关闭
  • 增加cursor不为null的判断,避免操作空游标
  • 把空的catch块改成打印异常,方便你以后遇到其他数据库问题时排查
  • 在finally块里关闭cursor和db,避免资源泄漏

这样修改后,当输入错误的用户名或密码时,就能正常触发else分支的Toast提示,不会再崩溃了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:14:05