Flutter Secure Storage读取JWT时出现“Unexpected null value.”异常
问题分析与解决方案
你遇到的屏幕闪烁"Unexpected null value."错误,核心原因大概率是异步操作的状态未正确处理,或是API层异常未被完整捕获导致错误短暂暴露在UI上,以下是具体排查和修复方案:
1. UI层异步状态处理(最可能的原因)
如果你的UI直接调用API方法而未用FutureBuilder或类似方式处理异步状态,会导致在readJwt完成前,UI尝试访问未初始化的null值,触发错误后又因异步操作完成更新UI,最终出现错误闪烁的情况。
修复示例:用FutureBuilder包裹API调用
FutureBuilder<ApiResponse<List<TrainingReference>>>( future: apiService.getTrainingReferences(), builder: (context, snapshot) { // 等待异步操作完成时显示加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 捕获异步操作中的所有异常 if (snapshot.hasError) { return Text('加载失败: ${snapshot.error}'); } // 处理API返回的业务错误 final response = snapshot.data!; if (response.hasError) { return Text('业务错误: ${response.error}'); } // 正常渲染数据 return ListView.builder( itemCount: response.body!.length, itemBuilder: (context, index) { return ListTile(title: Text(response.body![index].name)); }, ); }, )
2. API层异常捕获优化
你当前的readJwt调用在try块外部,若抛出EmptyJwtException会直接传播到UI层,导致未处理的错误提示。需将readJwt移到try块内部,统一捕获所有异常。
修改后的getTrainingReferences方法
Future<ApiResponse<List<TrainingReference>>> getTrainingReferences() async { Logger.logApiRequest(_className, _methodGetTrainingReferences, ""); Uri url = Uri.http(_apiHost, "api/v1/workouts"); var apiResponse = ApiResponse<List<TrainingReference>>(); http.Response response; try { // 将readJwt移到try块内,确保异常被捕获 String jwt = await readJwt(); response = await http.get( url, headers: {HttpHeaders.authorizationHeader: 'Bearer $jwt'}, ); if (response.statusCode == 200) { apiResponse.body = (json.decode(response.body) as List) .map((e) => TrainingReference.fromJson(e)) .toList(); Logger.logApiResponse( _className, _methodGetTrainingReferences, response.body.toString()); } else { apiResponse.hasError = true; apiResponse.error = response.body; Logger.logApiNotSuccess(_className, _methodGetTrainingReferences, response.statusCode, response.body.toString()); } } catch (e) { apiResponse.hasError = true; // 区分自定义异常和通用异常 if (e is EmptyJwtException) { apiResponse.error = 'JWT令牌为空,请重新登录'; } else { apiResponse.error = '未知错误: ${e.toString()}'; } Logger.logApiResponse( _className, _methodGetTrainingReferences, e.toString()); // 若无需上层处理异常,可移除rethrow // rethrow; } return apiResponse; }
3. 额外排查点
- Web端存储验证:在Chrome开发者工具的
Application -> Local Storage中,检查是否存在flutter_secure_storage前缀的JWT键值对(插件会自动添加前缀),确认存储内容正常。 - 非空断言检查:排查UI层和模型解析代码中的
!非空断言,替换为null安全处理(比如用??提供默认值,或条件判断确保值非空),避免触发"Unexpected null value."错误。
内容的提问来源于stack exchange,提问作者Mota
相关产品推荐
相关产品推荐

