我有一个网络调用要执行。但在此之前,我需要检查设备是否有互联网连接。
这是我目前为止所做的:
var connectivityResult = new Connectivity().checkConnectivity();// User defined class
if (connectivityResult == ConnectivityResult.mobile ||
connectivityResult == ConnectivityResult.wifi) {*/
this.getData();
} else {
neverSatisfied();
}
上述方法行不通。
我已经创建了一个包,(我认为)可以可靠地处理这个问题。
在pub.dev上的包
这个包在GitHub上
欢迎讨论。你可以使用GitHub上的问题跟踪器。
我不再认为这是一个可靠的方法:
想在@Oren的回答中添加一些东西:你真的应该再添加一个catch,它将捕获所有其他异常(为了安全起见),或者只是完全删除异常类型并使用一个catch,它处理所有异常:
案例1:
try {
await Firestore.instance
.runTransaction((Transaction tx) {})
.timeout(Duration(seconds: 5));
hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
hasConnection = false;
} on TimeoutException catch(_) {
hasConnection = false;
} catch (_) {
hasConnection = false;
}
或者更简单…
案例2:
try {
await Firestore.instance
.runTransaction((Transaction tx) {})
.timeout(Duration(seconds: 5));
hasConnection = true;
} catch (_) {
hasConnection = false;
}
在@dennmatt的回答之后,我注意到InternetAddress。查找可能会返回成功的结果,即使互联网连接断开-我测试它从我的模拟器连接到我的家庭WiFi,然后断开我的路由器的电缆。我认为原因是路由器缓存了域查找结果,所以它不必在每个查找请求时查询DNS服务器。
不管怎样,如果你像我一样使用Firestore,你可以用一个空事务替换try-SocketException-catch块并捕获TimeoutExceptions:
try {
await Firestore.instance.runTransaction((Transaction tx) {}).timeout(Duration(seconds: 5));
hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
hasConnection = false;
} on TimeoutException catch(_) {
hasConnection = false;
}
另外,请注意,previousConnection是在async internet -check之前设置的,因此理论上,如果checkConnection()在短时间内被调用多次,那么在一行中可能有多个hasConnection=true或多个hasConnection=false。
我不确定@dennmatt是否故意这样做,但在我们的用例中没有副作用(setState只被调用两次,具有相同的值)。
使用
dependencies:
connectivity: ^0.4.2
我们从资源处得到的是
import 'package:connectivity/connectivity.dart';
Future<bool> check() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
未来对我来说没什么问题,我们必须每次都实现它,比如:
check().then((intenet) {
if (intenet != null && intenet) {
// Internet Present Case
}
// No-Internet Case
});
所以为了解决这个问题,我创建了一个类,它接受一个布尔isNetworkPresent参数的函数,就像这样
methodName(bool isNetworkPresent){}
实用工具类是
import 'package:connectivity/connectivity.dart';
class NetworkCheck {
Future<bool> check() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
dynamic checkInternet(Function func) {
check().then((intenet) {
if (intenet != null && intenet) {
func(true);
}
else{
func(false);
}
});
}
}
并使用连接检查实用程序
fetchPrefrence(bool isNetworkPresent) {
if(isNetworkPresent){
}else{
}
}
我将使用这种语法
NetworkCheck networkCheck = new NetworkCheck();
networkCheck.checkInternet(fetchPrefrence)
我写了一个包来检查活跃的互联网连接和显示相应的小部件。
flutter_no_internet_widget
例子:
InternetWidget(
online: Text('Online'),
offline: Text('Offline),
);
根据网络状态,将显示适当的小部件。如果您有一个活跃的互联网连接,一个在线小部件将显示。
所有重量级的工作都由包完成,您所要做的就是提供在线和离线小部件。您还可以提供一个加载小部件和查找URL。
欢迎讨论、提交意见书或提出建议。
我已经创建了一个包,(我认为)可以可靠地处理这个问题。
在pub.dev上的包
这个包在GitHub上
欢迎讨论。你可以使用GitHub上的问题跟踪器。
我不再认为这是一个可靠的方法:
想在@Oren的回答中添加一些东西:你真的应该再添加一个catch,它将捕获所有其他异常(为了安全起见),或者只是完全删除异常类型并使用一个catch,它处理所有异常:
案例1:
try {
await Firestore.instance
.runTransaction((Transaction tx) {})
.timeout(Duration(seconds: 5));
hasConnection = true;
} on PlatformException catch(_) { // May be thrown on Airplane mode
hasConnection = false;
} on TimeoutException catch(_) {
hasConnection = false;
} catch (_) {
hasConnection = false;
}
或者更简单…
案例2:
try {
await Firestore.instance
.runTransaction((Transaction tx) {})
.timeout(Duration(seconds: 5));
hasConnection = true;
} catch (_) {
hasConnection = false;
}