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

Android Studio中如何根据Spinner选中值跳转对应角色Activity

问题根因分析

  • 校验逻辑缺失:当前SQL查询仅匹配邮箱和密码,未加入用户角色匹配条件,只要账号密码正确,不管对应账号在库里的角色是不是你选的,都会往下走
  • 执行顺序完全颠倒:rs.next()返回true才代表查到了匹配的用户,你现在是查到用户就直接return,反而在查不到用户的时候执行跳转逻辑,这就是为什么不管校验成不成功都乱跳
  • 线程使用错误:doInBackground运行在工作线程,不能直接执行startActivity这类UI操作,所有页面跳转、Toast操作必须放到UI线程的onPostExecute里执行
  • Spinner取值对比错误:user_type.getSelectedItem()返回的是Object类型,直接和字符串对比永远返回false,必须先调用toString()转成字符串再对比

修正步骤

  1. 调整SQL查询逻辑,加入角色字段过滤(假设你库里用户表的角色字段名叫user_role,如果你的字段名不一样自行替换)
  2. 把跳转逻辑移到onPostExecute中,校验通过再执行跳转
  3. 修复Spinner取值和逻辑顺序问题
  4. 用PreparedStatement替代Statement避免SQL注入风险

修正后完整代码

private class login_Api extends AsyncTask<String,String,String>
{
    // 存储当前选中的角色,方便后续跳转使用
    private String selectedRole;

    @Override
    protected void onPreExecute()
    {
        Toast.makeText(LoginActivity.this, "logging-in ... ", Toast.LENGTH_SHORT).show();
        // 提前在UI线程拿到选中的角色,不要在工作线程操作UI控件
        selectedRole = user_type.getSelectedItem().toString().trim();
    }

    @Override
    protected String doInBackground(String... strings) {
        try {
            Connection con = connectionClass.CONN();
            if (con != null) {
                // 查询条件加入角色匹配,避免越权登录
                String query = "SELECT * FROM `users` WHERE email = ? and password = ? and user_role = ?";
                PreparedStatement pstmt = con.prepareStatement(query);
                pstmt.setString(1, texEmail.getText().toString().trim());
                pstmt.setString(2, texPassword.getText().toString().trim());
                pstmt.setString(3, selectedRole);
                ResultSet rs = pstmt.executeQuery();
                // 查到匹配的用户才返回成功标识
                if (rs.next()) {
                    // 返回用户id或者自定义的成功标识,不为空代表校验通过
                    return rs.getString(1);
                }
                // 没查到匹配的返回空,代表账号/密码/角色不匹配
                return null;
            }
            else {
                Log.d(TAG, "onPreExecute: 数据库连接失败");
                return "conn_error";
            }
        }
        catch (Exception e)
        {
            Log.d(TAG, "onPreExecute: 查询出错" + e.getMessage());
            return "error";
        }
    }

    @Override
    protected void onPostExecute(String result) {
        Log.d(TAG, "onPostExecute: "+result);
        if(result != null && !result.equals("error") && !result.equals("conn_error")) {
            Toast.makeText(LoginActivity.this, "Welcome... ", Toast.LENGTH_SHORT).show();
            // 校验通过后根据选中的角色跳转对应页面
            if (selectedRole.equals("Hospital")) {
                Intent intent1 = new Intent(LoginActivity.this, HospitalMain.class);
                startActivity(intent1);
                finish(); // 可选,关闭登录页避免按返回键回到登录页
            } else if (selectedRole.equals("Donor")) {
                Intent intent1 = new Intent(LoginActivity.this, AddHospitalActivity.class);
                startActivity(intent1);
                finish();
            }
            // 剩余第三类角色的跳转逻辑在此处补充即可
        }
        else
        {
            if(result.equals("conn_error")){
                Toast.makeText(LoginActivity.this, "数据库连接失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(LoginActivity.this, "账号/密码或角色不匹配", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

补充注意事项

  • 如果你的用户表角色字段名不是user_role,记得把SQL语句里的字段名替换成你实际使用的字段名
  • 不要明文存储密码到数据库,生产环境建议加密后存储,查询时也先把输入的密码加密再和库中数据匹配
  • AsyncTask已被官方废弃,后续迭代建议用Coroutines、RxJava或者WorkManager替代异步逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:45:02