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

如何解决Flutter登录中‘Null不是bool子类型’未处理异常

问题解决思路

核心原因

异常Unhandled Exception: type 'Null' is not a subtype of type 'bool'触发点在if (jsonBody['result'])这一行——你直接将jsonBody['result']当作布尔值判断,但该键对应的值为null,要么是后端返回的JSON里没有result字段,要么是字段名拼写错误。

修复步骤

  1. 先校验字段存在性
    在判断result值前,先检查该键是否存在,避免强制转换null为bool:

    // 替换原有的if (jsonBody['result'])
    if (jsonBody.containsKey('result') && jsonBody['result'] == true) {
    
  2. 修正键名的空格问题
    代码中多处键名带多余空格(比如'id '、'id_user_type '),如果后端返回的键名没有空格,会导致取值为null,引发后续问题,需统一去掉空格:

    // 原错误写法
    General.savePrefString(Const_Values.ID, jsonBody['id ']);
    General.savePrefString(Const_Values.ID_USER_TYPE, jsonBody['id_user_type ']);
    // 修正后
    General.savePrefString(Const_Values.ID, jsonBody['id']);
    General.savePrefString(Const_Values.ID_USER_TYPE, jsonBody['id_user_type']);
    // 对应的类型判断也要同步修正
    if(jsonBody['id_user_type'] == "2"){
    
  3. 增加异常捕获与日志输出
    为了快速排查后端返回的JSON结构问题,建议在解析后打印完整响应,同时捕获所有可能的异常:

    var jsonBody = jsonDecode(response.body);
    // 打印完整响应,方便排查结构问题
    print('Login API Response: $jsonBody');
    try {
        // 后续的登录逻辑
    } catch (e) {
        print('Login Error: $e');
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
                icon: Icon(Icons.error),
                content: Text('登录失败,请稍后重试'),
                actions: [TextButton(onPressed: () => Navigator.pop(context), child: Text("OK"))],
            ),
        );
    }
    
  4. 后端接口格式校验
    确认后端login.php返回的JSON必须包含result布尔字段,以及其他必要字段,示例正确格式:

    // 登录成功
    {"result": true, "id": "1", "user_name": "xxx", "email_address": "xxx@xxx.com", "pas": "xxx", "id_user_type": "2"}
    // 登录失败
    {"result": false, "msg": "邮箱或密码错误"}
    

完整修正后的代码

login() async {
    EasyLoading.show(status: 'loading...');
    try {
        final response = await http.post(
            Uri.parse("${Const_Values.BASEURL}login.php"),
            body: {"email_address": emailControllor.text, "pas": passwordControllor.text},
        );
        EasyLoading.dismiss();
        if (response.statusCode == 200) {
            var jsonBody = jsonDecode(response.body);
            print('Login API Response: $jsonBody');
            
            if (jsonBody.containsKey('result') && jsonBody['result'] == true) {
                General.savePrefString(Const_Values.ID, jsonBody['id'] ?? '');
                General.savePrefString(Const_Values.USER_NAME, jsonBody['user_name'] ?? '');
                General.savePrefString(Const_Values.EMAIL_ADDRESS, jsonBody['email_address'] ?? '');
                General.savePrefString(Const_Values.PASSWORD, jsonBody['pas'] ?? '');
                General.savePrefString(Const_Values.ID_USER_TYPE, jsonBody['id_user_type'] ?? '');
                
                if(jsonBody['id_user_type'] == "2"){
                    Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(builder: (context) => Main_Enduser_Serceen()),
                    );
                }else{
                    Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(builder: (context) => Main_Admin_Secreen()),
                    );
                }
            } else {
                showDialog(
                    context: context,
                    builder: (context) => AlertDialog(
                        icon: Icon(Icons.error),
                        content: Text(jsonBody['msg'] ?? '登录失败,请检查账号密码'),
                        actions: [
                            TextButton(
                                onPressed: () => Navigator.pop(context),
                                child: Text("OK"),
                            ),
                        ],
                    ),
                );
            }
        } else {
            showDialog(
                context: context,
                builder: (context) => AlertDialog(
                    icon: Icon(Icons.error),
                    content: Text('服务器请求失败,状态码:${response.statusCode}'),
                    actions: [TextButton(onPressed: () => Navigator.pop(context), child: Text("OK"))],
                ),
            );
        }
    } catch (e) {
        EasyLoading.dismiss();
        print('Login Exception: $e');
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
                icon: Icon(Icons.error),
                content: Text('网络异常,请检查网络连接'),
                actions: [TextButton(onPressed: () => Navigator.pop(context), child: Text("OK"))],
            ),
        );
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:44:53