如何使用HTTP请求(Flutter/Dart)检查互联网连接性?

8

这可能是一个初学者的问题,但如果用户没有互联网连接或获取数据需要太长时间,我该如何使我的响应抛出异常?

Future<TransactionModel> getDetailedTransaction(String crypto) async {
//TODO Make it return an error if there is no internet or takes too long!

 http.Response response = await http.get(crypto);

  return parsedJson(response);

   }

检查此问题的答案:https://dev59.com/XVUL5IYBdhLWcg3w4reQ - Pol
4个回答

24

你应该使用try catch块来包含它,像这样:

import 'package:http/http.dart' as http;

int timeout = 5;
try {
  http.Response response = await http.get('someUrl').
      timeout(Duration(seconds: timeout));
  if (response.statusCode == 200) {
    // do something
  } else {
    // handle it
  }
} on TimeoutException catch (e) {
  print('Timeout Error: $e');
} on SocketException catch (e) {
  print('Socket Error: $e');
} on Error catch (e) {
  print('General Error: $e');
}

如果手机意识到没有网络连接(例如WiFi和数据连接都关闭了),则Socket异常将立即被引发。

如果服务器回复时间过长或用户连接非常差等情况,则会在给定的超时时间后引发超时异常。

此外,请不要忘记处理响应代码不等于200的情况。


抱歉让你等这么久。非常感谢,它完美地运行了! - TB_98
@Uros 但是手机连接到WiFi仍然会出现套接字异常错误。 - s.j
没有网络连接只是SocketException抛出的原因之一,我的意思是可能还有其他问题导致SocketException被抛出。有没有办法准确地确定是否原因是没有网络连接? - Ehsan Askari
另外需要补充的是,TimeoutException 需要导入 'dart:async'; 而 SocketException 需要导入 'dart:io'; - A5H1Q

2

您不需要使用http自行检查连通性,只需使用connectivity库即可。


感谢您的输入!我在这个项目中使用了BLoC设计模式,所以这个解决方案最终并不兼容我的项目。 - TB_98
2
原帖问如何检查互联网连接,但 https://pub.dev/packages/connectivity 连通性库包页面明确指出:“在 Android 上,这并不意味着连接到互联网。例如,应用程序可能具有 wifi 访问权限,但可能是 VPN 或没有访问权限的酒店 WiFi。”。因此,这个答案并未解决发帖者的问题。 - Fabio Pagano

1
你可以使用这个插件 https://pub.dev/packages/data_connection_checker
这样你就可以在开始获取数据之前检查是否有连接,如果没有则向用户发出警告,说明没有网络连接。如果有网络连接,则继续获取数据。
我将在下面链接一些资源,其中已经完美地解释了这个问题:

https://www.youtube.com/watch?v=u_Xyqo6lhFE

在进行http调用之前,需要完成所有这些事情,但是如果在进行http调用时网络中断了,那么可以使用@uros提到的try catch块。请告诉我它是否有效。

那个解决方案很好,如果你想要检查整个应用程序的数据连接,但我只想在那个获取方法中检查连接。感谢您的帮助! - TB_98

0

这是我检查应用程序中的互联网连接的方法。

我创建了一个名为“connectivity”的公共类,并在应用程序中的任何地方使用它来检查连接性。我使用Flutter的connectivity包。

我的connectivity类

 Future<bool> check() async {
  var connectivityResult = await (Connectivity().checkConnectivity());
  if (connectivityResult == ConnectivityResult.mobile) {
    return true;
  } else if (connectivityResult == ConnectivityResult.wifi) {
    return true;
  }
  return false;
}

然后我像这样使用这个类:

 @override
  void initState() {
    super.initState();

    checkInternetConnection().then((internet) {
      if (internet != null && internet) {
        // Internet Present Case
        // do your task;
      } else {
        // No-Internet Case
        showAlertDialog(context);
      }
    });
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接