Flutter GetX开发:RangeError与API 401未授权问题求助
GetX迁移问题排查方案
问题1:API 401 Invalid token
- 检查token的存储与读取:确认使用
GetStorage或其他方式存储的token不为空,且格式正确(比如是否包含Bearer前缀) - 验证token有效性:调用token校验接口确认token未过期,或检查登录接口返回的token是否符合后端要求
- 检查请求头配置:确保API请求时正确携带
Authorization头,示例:options: Options(headers: {'Authorization': 'Bearer $token'}) - 环境匹配:确认请求的API环境(测试/生产)与获取token的环境一致,避免跨环境使用无效token
问题2:HomePageController initBikeList方法RangeError(索引无效)
核心排查点:
列表是否为GetX可观察类型
普通List无法触发GetX的响应式更新,需声明为可观察列表:final bikeList = <Bike>[].obs;更新列表时需使用GetX提供的方法(如
assignAll、addAll),而非直接赋值,确保响应式生效:bikeList.assignAll(fetchedBikes); // 正确方式 // 避免:bikeList = fetchedBikes;异步加载时机问题
API请求是异步操作,若在数据返回前就访问列表索引(如bikeList[0]),会触发空列表索引错误。解决方式:- 在访问索引前先判断列表非空:
if (bikeList.isNotEmpty) { // 执行需要访问索引的逻辑 } - 使用
ever监听列表变化,在列表更新后执行依赖逻辑:@override void onInit() { super.onInit(); ever(bikeList, (updatedList) { if (updatedList.isNotEmpty) { // 处理更新后的列表 } }); initBikeList(); }
- 在访问索引前先判断列表非空:
异常捕获与兜底
在initBikeList中添加异常捕获,避免崩溃并定位问题:Future<void> initBikeList() async { try { // API请求与列表更新逻辑 } catch (e) { if (e is RangeError) { print('列表为空,无法访问索引'); } // 其他异常处理 } }
综合代码示例
import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:dio/dio.dart'; class HomePageController extends GetxController { // 声明GetX可观察列表 final bikeList = <Bike>[].obs; Future<void> initBikeList() async { try { // 读取本地token,校验有效性 final token = GetStorage().read('auth_token'); if (token == null) { Get.offAll(() => LoginPage()); return; } // 发起API请求,携带正确的Authorization头 final response = await Dio().get( 'https://your-api-url/bikes', options: Options( headers: {'Authorization': 'Bearer $token'}, ), ); // 解析数据并更新可观察列表 final fetchedBikes = (response.data as List) .map((json) => Bike.fromJson(json)) .toList(); bikeList.assignAll(fetchedBikes); // 确保列表非空后再访问索引 if (bikeList.isNotEmpty) { // 示例:处理第一个元素 print('第一个自行车:${bikeList[0].name}'); } else { print('未获取到自行车数据'); } } on DioException catch (e) { if (e.response?.statusCode == 401) { // token无效,清除本地存储并跳转登录 GetStorage().remove('auth_token'); Get.offAll(() => LoginPage()); print('Token无效,请重新登录'); } else { print('API请求失败:${e.message}'); } } catch (e) { print('初始化自行车列表失败:$e'); } } @override void onInit() { super.onInit(); initBikeList(); } } // 假设的Bike模型类 class Bike { final String name; Bike({required this.name}); factory Bike.fromJson(Map<String, dynamic> json) { return Bike(name: json['name']); } }
内容的提问来源于stack exchange,提问作者weaked
相关产品推荐
相关产品推荐

