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

登录验证崩溃求助:SQLite语法错误与登录逻辑缺陷排查

咱们先从崩溃的核心问题说起,再一步步修复逻辑漏洞:

问题根源拆解

1. 直接导致崩溃的SQL语法错误

看Logcat里的关键报错:

android.database.sqlite.SQLiteException: no such column: parent (code 1): , while compiling: select * from Parents_Table where (EMAIL_ADDRESS = parent OR PHONE_NUMBER = parent) AND PASSWORD = 123456

你把用户输入的字符串(比如parent)直接拼进SQL语句,却没加单引号,SQL引擎会把parent当成列名而非字符串值,自然找不到这个列,直接抛出崩溃异常。

2. LoginActivity的致命逻辑漏洞

  • if(true) 这个条件永远成立,不管登录成功失败都会跳转到首页,完全跳过了错误反馈逻辑
  • parentModel 从未初始化,直接调用parentModel.getID()会触发空指针异常

完整修复方案

第一步:修复DatabaseHelper的SQL注入&语法问题

永远不要直接拼接用户输入到SQL里,改用参数化查询(既安全又避免语法错误):

// 修复userExistance方法
public boolean userExistance(String emailOrPhone, String pwd) {
    // 使用?作为占位符,避免SQL注入和语法错误
    String sql = "select * from " + TABLE_NAME + " where (" + COL_3 + " = ? OR " + COL_4 + " = ?) AND " + COL_5 + " = ?";
    SQLiteDatabase mydb = this.getReadableDatabase(); // 查询用可读数据库即可
    Cursor cursor = mydb.rawQuery(sql, new String[]{emailOrPhone, emailOrPhone, pwd});
    
    boolean exists = cursor.getCount() > 0;
    cursor.close(); // 记得关闭Cursor,避免内存泄漏
    mydb.close();
    return exists;
}

// 同步修复getParentLoginData方法(避免同样问题)
public ArrayList<ParentModel> getParentLoginData(String emailOrPhone,String password){
    ArrayList<ParentModel> list = new ArrayList<>();
    String sql = "SELECT * FROM " + TABLE_NAME+" WHERE ("+COL_3+"= ? OR "+COL_4 +" = ?) AND "+COL_5 +" = ?";
    SQLiteDatabase mydb = this.getReadableDatabase();
    Cursor cursor = mydb.rawQuery(sql, new String[]{emailOrPhone, emailOrPhone, password});
    
    if (cursor.moveToFirst()) {
        do {
            ParentModel parentModel = new ParentModel();
            parentModel.setID(cursor.getString(0));
            parentModel.setName(cursor.getString(1));
            parentModel.setSurname(cursor.getString(2));
            parentModel.setEmail(cursor.getString(3));
            parentModel.setPhone_number(cursor.getString(4));
            parentModel.setPassword(cursor.getString(5));
            list.add(parentModel);
        } while (cursor.moveToNext());
    }
    cursor.close();
    mydb.close();
    return list;
}

第二步:修复LoginActivity的逻辑错误

替换userLogin方法里的核心判断逻辑:

private void userLogin() {
    String email = editTextEmailPhone.getText().toString().trim();
    String password = editTextPassword.getText().toString().trim();

    if (email.isEmpty()) {
        editTextEmailPhone.setError("Email or Phone Number is required");
        editTextEmailPhone.requestFocus();
        return;
    }
    if (password.isEmpty()) {
        editTextPassword.setError("Password is required");
        editTextPassword.requestFocus();
        return;
    }
    if (password.length()<6 ){
        editTextPassword.setError("Minimum of length of password should be 6");
        editTextPassword.requestFocus();
        return;
    }

    progressDialog.setMessage("Please Wait...");
    progressDialog.show();

    boolean exists = mydb.userExistance(email, password);
    if(exists) {
        // 获取登录用户的详细数据
        ArrayList<ParentModel> parentList = mydb.getParentLoginData(email, password);
        if(!parentList.isEmpty()){
            parentModel = parentList.get(0);
        }
        
        progressDialog.dismiss();
        SharedPrefs.saveSharedSetting(this, "NoAccount", "false");
        Intent intent = new Intent(Login.this, Parent_Home.class);
        
        // 存储用户信息到SharedPreferences(替代Intent传参更持久)
        SharedPrefs.saveSharedSetting(this, "CurrentParentID", parentModel.getID());
        SharedPrefs.saveSharedSetting(this, "CurrentParentName", parentModel.getName());
        SharedPrefs.saveSharedSetting(this, "CurrentParentSurname", parentModel.getSurname());
        
        Toast.makeText(this, "Welcome " + parentModel.getName(), Toast.LENGTH_SHORT).show();
        startActivity(intent);
        finish();
    } else {
        // 显示预期的错误提示
        Toast.makeText(getApplicationContext(), "凭证错误,请检查账号密码", Toast.LENGTH_SHORT).show();
        progressDialog.dismiss();
        return;
    }
}

第三步:额外优化(避免潜在问题)

  • 在LoginActivity的onCreate方法里初始化parentModel:parentModel = new ParentModel();,防止空指针
  • 所有数据库操作完成后关闭Cursor和Database,避免内存泄漏
  • 不要明文存储密码,后续可以改成存储密码的哈希值(比如SHA-256),提升安全性

测试验证

修复后测试场景:

  1. 输入错误凭证:弹出**"凭证错误,请检查账号密码"**的Toast,程序正常运行
  2. 输入正确凭证:正常跳转到首页,显示欢迎Toast

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:29:32