Flutter使用Dio获取带重定向图片时遇主机查找失败及应用冻结问题
问题原因分析
- 未捕获的空指针异常:在
catch块中直接使用e.response!强制解包,当出现Failed host lookup这类无响应的错误时,e.response为null,强制解包会触发未捕获的空指针异常,导致应用崩溃。 - 逻辑覆盖错误:无论
try块中请求是否成功,最后都会强制将authorModel赋值为默认头像的实例,导致之前的请求结果完全无效。 - 不必要的资源浪费:使用
dio.get()请求图片会默认下载完整二进制数据,但你的需求只是获取重定向后的URL,这会额外消耗带宽,甚至可能因资源加载阻塞导致应用卡顿。
解决方案
1. 修复异常捕获逻辑
避免强制解包e.response,先判断其是否为空再处理错误:
2. 修正逻辑覆盖问题
仅在请求失败时设置默认头像,保留成功请求的结果:
3. 优化请求方式
使用HEAD请求替代GET,只获取响应头和重定向地址,无需下载图片内容,大幅提升性能:
4. 检查网络权限
- Android:在
android/app/src/main/AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - iOS:确保
ios/Runner/Info.plist中允许网络访问(HTTPS默认支持,若需HTTP需添加对应例外)。
修正后的完整代码
class WordpressAPI { // ... static Future<AuthorModel> fetchAuthorInformation(int id) async { try { var link = 'https://secure.gravatar.com/avatar/37ae806a1e430886229d45923d8414d4?s=64&d=https%3A%2F%2Fshiftdelete.net%2Fwp-content%2Fthemes%2Fshiftdelete%2Fassets%2Fimg%2Favatar.png&r=g'; // 使用HEAD请求获取重定向地址,无需下载图片 final imageResponse = await dio.head( link, options: Options( followRedirects: true, validateStatus: (status) => status! < 500, // 允许重定向状态码 ), ); final realImageUrl = imageResponse.realUri.toString(); print(realImageUrl); return AuthorModel( id: id, name: 'name', image: realImageUrl, ); } on DioException catch (e) { // 分情况处理错误 if (e.response != null) { print('HTTP错误:${e.response!.statusCode}'); } else { print('请求错误:${e.message}'); } // 请求失败时返回默认头像 return AuthorModel( id: id, name: 'name', image: GetImageURL.authorDefaultAvatar, ); } } // ... }
额外提示
- 如果在UI线程中调用该方法(比如
initState),建议使用FutureBuilder配合异步逻辑,避免阻塞UI导致冻结。 - 可以给Dio添加全局超时配置,防止请求长时间无响应:
Dio dio = Dio(BaseOptions( connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 5), ));
内容的提问来源于stack exchange,提问作者Burak Soyman
相关产品推荐
相关产品推荐

