写完了监听网络变化的demo,发现其实代码很短,但是涉及到的知识点却是很多:比如Stream,异步生成器,yield,async* 和async的区别,Future等关于Dart的基础知识。在这里暂且为了博文不跑题不会做多说明(有些我还没研究呢,写了怕打脸),后面会专门写关于Stream的博客。不了解童鞋可以参考博文后面的资料。闲言少叙书归正传:
监听网络变化需要引入connectivity库,具体在pubspec.yaml种做如下配置:
dev_dependencies:
flutter_test:
sdk: flutter
connectivity: 0.3.2
在对应的Dart文件种添加import:
import 'package:connectivity/connectivity.dart';
网络监听的结果最终封装成ConnectivityResult :
enum ConnectivityResult { wifi, mobile, none }
可以看出connectivity对网络状态的监听分成了三种:wifi链接,移动信号链接,以及无网络三种状态。
且获取当前网络状态的代码也很简单,根据Connectivity 对象的checkConnectivity方法获取当前网络状态:
Connectivity connectivity = Connectivity();
ConnectivityResult previousResult = await connectivity.checkConnectivity();
或者:
connectivity.checkConnectivity().then((ConnectivityResult connectivityResult) {
print("current connect type =="+connectivityResult.toString());
});
因为checkConnectivity方法返回的是一个Future,所以需要用await,或者直接用then方法,checkConnectivity方法返回的是当前网络的状态。但是我们怎么监听网络状态发生改变呢?有一个思路就是写一个类似定时器的东西,每隔一段时间调用checkConnectivity方法,但是这肯定不优雅。最主要的是Future主动是我们主动获取数据,属于“拉”数据的过程。那么当网络数据发生改变的时候,能不能把这个数据主动“推”给我们呢?此时Stream就有了用武之地。
在Connectivity种也提供了一个变量,该变量就是返回了一个Stream:
Stream<ConnectivityResult> _onConnectivityChanged;
/// Fires whenever the connectivity state changes.
//当网络状态发生改变的时候会发射改变状态的数据ConnectivityResult
Stream<ConnectivityResult> get onConnectivityChanged {
if (_onConnectivityChanged == null) {
_onConnectivityChanged = _eventChannel
.receiveBroadcastStream()
.map((dynamic event) => _parseConnectivityResult(event));
}
return _onConnectivityChanged;
}
所以我们就可以用如下代码来进行网络状态监听:
///定义一个异步生成器
Stream<ConnectivityResult> connectChangeListener() async* {
final Connectivity connectivity = Connectivity();
///遍历onConnectivityChanged 构成的 Stream<ConnectivityResult>
await for (ConnectivityResult result in connectivity.onConnectivityChanged) {
//状态发生改变后将状态值添加到Stream数据流中
yield result;
}
}
所以有了connectChangeListener我们就可以进行网络状态的监听了,当网络状态发生改变时,主动通知我们,我们来做相应的处理逻辑:比如在视频播放过程中无网络的时候暂停,有网络的时候自动播放等逻辑。
StreamSubscription<ConnectivityResult> connectivitySubscription;
bool connected = false;
@override
void initState() {
super.initState();
///当网络状态发生改变的时候,会调用listen回调
connectivitySubscription = connectChangeListener().listen( (ConnectivityResult connectivityResult) {
if (!mounted) {
return;
}
setState(() {
///是否有网络
connected = connectivityResult != ConnectivityResult.none;
});
},
);
}
Stream通过listen的执行来开发发送数据,该方法返回了一个StreamSubscription对象,我们可以通过StreamSubscription对象来终止数据的接收:
@override
void dispose() {
connectivitySubscription.cancel();
super.dispose();
}
从这个小demo有一种,麻雀虽小,五脏俱全的味道,涉及到了Stream,Future,async*,yield等Dart的基础知识点,而这方面博主的经验还比较欠缺,Flutter的学习任重而道远。
参考资料:
Using Streams in Flutter:
Reactive Programming — Streams — BLoC:
Exploring Streams in Flutter:
Dart学习笔记(29):异步编程:
成器
最后源码奉上,因为很短,所以直接贴代码了:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:connectivity/connectivity.dart';
class ConnectWidget extends StatefulWidget {
const ConnectWidget();
@override
_ConnectState createState() => _ConnectState();
}
class _ConnectState extends State<ConnectWidget> {
Stream<ConnectivityResult> connectChangeListener() async* {
final Connectivity connectivity = Connectivity();
await for (ConnectivityResult result
in connectivity.onConnectivityChanged) {
yield result;
}
}
StreamSubscription<ConnectivityResult> connectivitySubscription;
bool connected = false;
@override
void initState() {
super.initState();
connectivitySubscription = connectChangeListener().listen( (ConnectivityResult connectivityResult) {
if (!mounted) {
return;
}
setState(() {
connected = connectivityResult != ConnectivityResult.none;
});
},
);
}
@override
void dispose() {
connectivitySubscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text(connected?"有网络链接":"断网了"),),
);
}
}