Flutter监听网络变化

写完了监听网络变化的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?"有网络链接":"断网了"),),
    );
  }
}

    原文作者:chunqiuwei
    原文地址: https://blog.csdn.net/chunqiuwei/article/details/89457829
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞