Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听)

news2025/3/26 12:38:11

Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听)

目录

Flutter 学习之旅 之 flutter 使用 connectivity_plus 进行网路状态监听(断网/网络恢复事件监听)

一、简单介绍

二、connectivity_plus

1、connectivity_plus 实现断网和网络连接状态的事件监听原理

2、使用 connectivity_plus 的注意事项

三、安装 connectivity_plus

四、简单效果

五、简单案例实现

六、关键代码


一、简单介绍

Flutter 是一款开源的 UI 软件开发工具包,由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序,包括移动设备(iOS 和 Android)、Web 和桌面平台(Windows、macOS 和 Linux)。

Flutter 使用 Dart 编程语言,它可以将代码编译为 ARM 或 Intel 机器代码以及 JavaScript,从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库,开发者可以根据自己的需求灵活地控制每个像素,从而创建自定义的、适应性强的设计,这些设计在任何屏幕上都能呈现出色的外观和感觉。

 

二、connectivity_plus

网址:connectivity_plus | Flutter package

connectivity_plus 是一个 Flutter 插件,用于监听设备的网络状态变化,包括 Wi-Fi、移动网络和无网络连接等状态。它通过提供一个简单的 API,允许开发者实时获取网络连接状态,并在状态发生变化时接收通知。通过订阅网络状态变化的流,开发者可以在应用中实现动态响应网络变化的功能,例如提示用户网络连接问题或调整应用的行为。

1、connectivity_plus 实现断网和网络连接状态的事件监听原理

connectivity_plus 插件通过监听设备的网络连接变化事件来实现网络状态的监听。它利用了底层平台(如 Android 和 iOS)提供的网络状态检测能力,并通过 Dart 的 Stream 提供实时更新。

  • Android:在 Android 上,connectivity_plus 使用 ConnectivityManager 来监听网络状态变化。当网络连接类型发生变化时(如从 Wi-Fi 切换到移动网络,或网络断开),系统会触发事件,插件捕获这些事件并通过 Dart 的 Stream 传递给 Flutter 应用。

  • iOS:在 iOS 上,插件通过 Network 框架的 NWPathMonitor 来监听网络路径的变化。当网络状态发生变化时,插件会收到通知,并将这些变化通过 Stream 传递给 Flutter 应用。

2、使用 connectivity_plus 的注意事项

  • 网络状态的不确定性
    • 即使插件报告了网络连接类型(如 Wi-Fi 或移动网络),也不能保证该网络一定可以访问互联网。例如,某些 Wi-Fi 网络可能需要用户登录才能访问互联网。

    • 开发者应始终准备处理网络请求的超时和错误,而不是完全依赖当前的网络状态。

  • 权限要求

    • 在某些平台上(如 Android 和 iOS),需要在应用的配置文件中声明网络状态监听权限。例如,在 Android 上需要在 AndroidManifest.xml 中添加 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  • 资源管理

    • 监听网络状态变化时,需要使用 StreamSubscription 订阅 onConnectivityChanged 流。在不再需要监听时,必须调用 cancel() 方法取消订阅,以避免资源泄漏。

  • 初始化检查

    • 在应用启动时,建议调用 checkConnectivity() 方法获取当前的网络状态,以确保应用在启动时就能正确处理网络状态。

  • 用户体验

    • 在某些场景下(如用户未授权网络访问权限),应用可能会出现短暂的无网络状态。开发者可以通过在开屏页提示用户授权网络访问,来改善用户体验。

通过合理使用 connectivity_plus 插件并注意上述事项,开发者可以在 Flutter 应用中有效地管理网络状态,提升应用的健壮性和用户体验。

三、安装 connectivity_plus

1、直接运行命令

使用 Flutter:flutter pub add connectivity_plus

2、或者在 pubspec.yaml 添加

dependencies:
  connectivity_plus: ^6.1.3

四、简单效果

五、简单案例实现

1、这里使用 Android Studio 进行创建 Flutter 项目

2、创建一个 application 的 Flutter 项目

3、项目结构如下

4、实现一个 NetworkStatusManager 类,监听网络断开和恢复的事件

5、在 main 测试 网络网络断开和恢复的事件监听功能

6、连接设备,运行简单效果如下

六、关键代码

1、NetworkStatusManager

import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';

// 定义回调函数类型
// 网络状态变化时的回调函数,参数为当前的网络状态列表
typedef NetworkStatusCallback = void Function(List<ConnectivityResult> result);

// 网络连接时的回调函数,无参数
typedef NetworkConnectedCallback = void Function();

// 网络断开时的回调函数,无参数
typedef NetworkDisconnectedCallback = void Function();

class NetworkStatusManager {
  // 使用 Connectivity 插件实例来监听网络状态变化
  final Connectivity _connectivity = Connectivity();

  // StreamSubscription 用于订阅网络状态变化事件
  late StreamSubscription<List<ConnectivityResult>> _connectivitySubscription;

  // 定义回调函数
  // 网络状态变化时的回调函数
  late NetworkStatusCallback _onNetworkChanged;

  // 网络连接时的回调函数
  late NetworkConnectedCallback _onNetworkConnected;

  // 网络断开时的回调函数
  late NetworkDisconnectedCallback _onNetworkDisconnected;

  // 初始化网络状态管理器
  // 参数:
  // - onNetworkChanged:网络状态变化时的回调函数
  // - onNetworkConnected:网络连接时的回调函数
  // - onNetworkDisconnected:网络断开时的回调函数
  void initNetworkStatusManager({
    required NetworkStatusCallback onNetworkChanged,
    required NetworkConnectedCallback onNetworkConnected,
    required NetworkDisconnectedCallback onNetworkDisconnected,
  }) {
    // 保存回调函数
    _onNetworkChanged = onNetworkChanged;
    _onNetworkConnected = onNetworkConnected;
    _onNetworkDisconnected = onNetworkDisconnected;

    // 监听网络状态变化
    // 使用 _connectivity.onConnectivityChanged 获取网络状态变化的流
    // 并订阅该流,当网络状态变化时调用 _handleConnectivityChange 方法
    _connectivitySubscription =
        _connectivity.onConnectivityChanged.listen(_handleConnectivityChange);
  }

  // 处理网络状态变化
  // 参数:
  // - result:当前的网络状态列表
  void _handleConnectivityChange(List<ConnectivityResult> result) {
    // 调用网络状态变化的回调函数
    _onNetworkChanged?.call(result);

    // 检查网络状态
    // 如果 result 中包含 ConnectivityResult.none,则认为网络断开
    if (result.contains(ConnectivityResult.none)) {
      // 调用网络断开的回调函数
      _onNetworkDisconnected?.call();
    } else {
      // 否则认为网络连接
      // 调用网络连接的回调函数
      _onNetworkConnected?.call();
    }
  }

  // 取消监听
  // 释放资源,取消对网络状态变化事件的订阅
  void dispose() {
    _connectivitySubscription.cancel();
  }
}

代码说明

  1. 回调函数类型定义

    • NetworkStatusCallback:当网络状态发生变化时调用,参数为当前的网络状态列表。

    • NetworkConnectedCallback:当网络连接时调用,无参数。

    • NetworkDisconnectedCallback:当网络断开时调用,无参数。

  2. 类成员变量

    • _connectivityConnectivity 插件实例,用于监听网络状态变化。

    • _connectivitySubscription:用于订阅网络状态变化事件的 StreamSubscription

    • _onNetworkChanged_onNetworkConnected_onNetworkDisconnected:分别用于处理网络状态变化、网络连接和网络断开的回调函数。

  3. initNetworkStatusManager 方法

    • 初始化网络状态管理器,接收三个回调函数作为参数。

    • 订阅网络状态变化事件,当网络状态变化时调用 _handleConnectivityChange 方法。

  4. _handleConnectivityChange 方法

    • 处理网络状态变化事件。

    • 调用 _onNetworkChanged 回调函数,通知调用者网络状态已变化。

    • 根据网络状态调用 _onNetworkConnected_onNetworkDisconnected 回调函数。

  5. dispose 方法

    • 取消对网络状态变化事件的订阅,释放资源。

2、main

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'network_status_manager.dart'; // 假设你将上述代码保存为 network_status_manager.dart

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 创建一个 MaterialApp,这是 Flutter 应用的根组件
    return MaterialApp(
      title: 'Flutter Demo', // 应用的标题
      theme: ThemeData(
        // 定义应用的主题
        useMaterial3: true, // 使用 Material Design 3
        colorSchemeSeed: const Color(0x9f4376f8), // 主题颜色种子
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'), // 应用的首页
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  // 页面的标题
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 当前的网络状态列表,默认为 [ConnectivityResult.none],表示没有网络连接
  List<ConnectivityResult> _connectionStatus = [ConnectivityResult.none];

  // 网络状态管理器实例
  late NetworkStatusManager _networkStatusManager;

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

    // 创建一个 NetworkStatusManager 实例
    _networkStatusManager = NetworkStatusManager();

    // 初始化网络状态管理器,并设置回调函数
    _networkStatusManager.initNetworkStatusManager(
      onNetworkChanged: (result) {
        // 当网络状态发生变化时,更新 _connectionStatus 并刷新 UI
        setState(() {
          _connectionStatus = result;
        });
        // 打印网络状态变化
        print('Network status changed: $_connectionStatus');
      },
      onNetworkConnected: () {
        // 当网络连接时,打印日志
        print('Network connected');
      },
      onNetworkDisconnected: () {
        // 当网络断开时,打印日志
        print('Network disconnected');
      },
    );
  }

  @override
  void dispose() {
    // 释放资源,取消对网络状态变化事件的订阅
    _networkStatusManager.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 构建页面的 UI
    return Scaffold(
      appBar: AppBar(
        // 页面的标题栏
        title: const Text('Network Status Example'),
        elevation: 4, // 标题栏的阴影高度
      ),
      body: Column(
        // 页面的主体内容,使用 Column 布局
        mainAxisSize: MainAxisSize.min, // 设置 Column 的最小高度
        children: [
          const Spacer(flex: 2), // 添加一个占位符,用于间距
          Text(
            // 显示当前的网络状态标题
            'Active connection types:',
            style: Theme.of(context).textTheme.headlineMedium, // 使用主题的标题样式
          ),
          const Spacer(), // 添加一个占位符,用于间距
          ListView(
            // 使用 ListView 显示当前的网络状态列表
            shrinkWrap: true, // 允许 ListView 自动调整大小
            children: _connectionStatus.map((status) {
              // 遍历 _connectionStatus 列表,生成每个网络状态的文本
              return Center(
                child: Text(
                  status.toString(), // 显示网络状态的字符串表示
                  style: Theme.of(context).textTheme.headlineSmall, // 使用主题的小标题样式
                ),
              );
            }).toList(),
          ),
          const Spacer(flex: 2), // 添加一个占位符,用于间距
        ],
      ),
    );
  }
}

代码说明

  1. MyApp

    • 这是 Flutter 应用的根组件,负责创建 MaterialApp,配置应用的主题和首页。

    • MaterialApp 是 Flutter 中用于创建 Material Design 风格应用的组件。

  2. MyHomePage

    • 这是一个 StatefulWidget,表示应用的首页。

    • 它包含一个 title 属性,用于显示页面的标题。

  3. _MyHomePageState

    • 这是 MyHomePage 的状态类,用于管理页面的状态和逻辑。

    • _connectionStatus:用于存储当前的网络状态列表。

    • _networkStatusManager:用于管理网络状态监听的实例。

  4. initState 方法

    • 在页面初始化时调用。

    • 创建 NetworkStatusManager 实例,并初始化网络状态管理器。

    • 设置三个回调函数:

      • onNetworkChanged:当网络状态发生变化时调用,更新 _connectionStatus 并刷新 UI。

      • onNetworkConnected:当网络连接时调用,打印日志。

      • onNetworkDisconnected:当网络断开时调用,打印日志。

  5. dispose 方法

    • 在页面销毁时调用。

    • 释放资源,取消对网络状态变化事件的订阅。

  6. build 方法

    • 构建页面的 UI。

    • 使用 Scaffold 创建一个带标题栏的页面。

    • 使用 Column 布局,显示当前的网络状态标题和网络状态列表。

    • 使用 ListView 遍历 _connectionStatus 列表,生成每个网络状态的文本。

测试结果

运行上述代码后,应用将正确监听网络状态的变化:

  • 当网络连接时,会调用 onNetworkConnected 回调函数,并打印 "Network connected"。

  • 当网络断开时,会调用 onNetworkDisconnected 回调函数,并打印 "Network disconnected"。

  • 同时,onNetworkChanged 回调函数会更新 _connectionStatus,并在 UI 中显示当前的网络连接类型。

希望这些注释和代码对你有帮助!如果有任何问题,请随时告诉我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2320826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redisson 分布式锁原理

加锁原理 # 如果锁不存在 if (redis.call(exists, KEYS[1]) 0) then# hash结构,锁名称为key,线程唯一标识为itemKey&#xff0c;itemValue为一个计数器。支持相同客户端线程可重入,每次加锁计数器1.redis.call(hincrby, KEYS[1], ARGV[2], 1);# 设置过期时间redis.call(pexpi…

【STM32】SPI通信外设硬件SPI读写W25Q64

SPI通信协议和W25Q64存储器芯片解读笔记&#xff1a; 【STM32】SPI通信协议&W25Q64Flash存储器芯片&#xff08;学习笔记&#xff09;-CSDN博客 SPI通信外设 SPI外设简介 STM32内部集成了硬件SPI收发电路&#xff0c;可以由硬件自动执行时钟生成、数据收发等功能&…

Spring JDBC Template与事务管理:基于XML与注解的实战指南

摘要 本文深入解析Spring JDBC Template与事务管理的核心技术&#xff0c;结合XML配置与注解方式两种主流方案&#xff0c;通过转账案例完整演示数据库操作与事务管理的最佳实践。文章涵盖JDBC Template的核心用法、事务配置语法、常见问题及性能优化建议&#xff0c;帮助开发…

【Keil5-开发技巧】

Keil5-开发技巧 ■ Keil5利用AStyle插件格式化代码第一步:下载AStyle插件第二步:添加AStyle插件第三步:AStyle插件介绍■ 一键转UTF-8编码■ Keil5利用AStyle插件格式化代码 第一步:下载AStyle插件 AStyle下载 第二步:添加AStyle插件 解压后 astyle-3.6.7-x64 在重命…

电脑上不了网普通用户排除方法

1&#xff1a;首先通过电脑的运行/CMD/ipconfig /all 命令查看电脑的ip地址是否正常如图&#xff1a; 2&#xff1a;在命令行中运行&#xff1a;ping 127.0.0.1 如图则正常&#xff0c;否则要重新安装网卡驱动 程序。 3&#xff1a;用ping命令&#xff0c;ping一下同网段的电…

【C#】WinForm自定义控件及窗体

前言 WinForm&#xff08;Windows Forms&#xff09;是Microsoft.NET框架中的技术&#xff0c;用于开发Windows桌面应用程序。它提供了一套丰富的控件和组件。通过拖放控件、编写事件处理程序等方式快速构建用户界面。 通过属性窗口定制这些控件的外观和行为。 通过数据绑定&am…

基于虚拟知识图谱的语义化决策引擎

在数字化转型浪潮中&#xff0c;企业数据资产的价值释放面临两大挑战&#xff1a;海量异构数据的整合困局与业务-技术语义鸿沟。本文解析飞速创软灵燕智能体平台的创新解决方案——通过构建业务语义驱动的虚拟知识图谱系统&#xff0c;实现企业数据的智能认知与决策赋能。 一、…

HarmonyOS:@AnimatableExtend 装饰器自学指南

在最近的项目开发中&#xff0c;我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中&#xff0c;我发现了 AnimatableExtend 装饰器&#xff0c;它为实现动画效果提供了一种非常灵活且强大的方式。然而&#xff0c;在学习这个装饰器的过程中&#xff0c;我发现相关的…

kubernetes|云原生|kubeadm-1.25.7集群单master+外部etcd集群+kubeadm-init+cri-docker文件形式快速部署

一、 前言和写作原因 本文做一个kubernetes集群部署记录&#xff0c;实在是部署的东西太多了&#xff0c;害怕忘记&#xff0c;kubernetes集群的部署又细节比较多&#xff0c;因此&#xff0c;在这里做一个尽量详细的记录 三个VMware虚拟机&#xff0c;IP分别为192.168.123.…

Qt 导入TagLib库

文章目录 0. 前言和环境介绍1. 下载TagLib2. 下载zlib3. 修改.pro文件4. 测试代码 0. 前言和环境介绍 最近在使用Qt写一个播放器&#xff0c;需要解析mp3文件&#xff0c;于是研究了一下如何导入TagLib库 Qt构建套件:Desktop Qt6.8.2 MinGW64-bit Qt Creator安装目录: D:\bit…

新能源汽车充换站如何实现光储充一体化管理?

长三角某换电站光伏板晒到发烫&#xff0c;却因电网限电被迫切机&#xff1b;北京五环充电站每月多缴6万超容费&#xff1b;深圳物流车充电高峰排队3小时...当95%的充换站深陷“用不起绿电、扛不住扩容、算不清碳账”困局&#xff0c;安科瑞用一组真实数据撕开行业潜规则&#…

【数据分享】2000—2024年我国省市县三级逐年归一化植被指数(NDVI)数据(年平均值/Shp/Excel格式)

之前我们分享过2000-2024年我国逐年的归一化植被指数&#xff08;NDVI&#xff09;栅格数据&#xff0c;该逐年数据是取的当年月归一化植被指数&#xff08;NDVI&#xff09;的年平均值。&#xff01;该数据来源于NASA定期发布的MOD13A3数据集&#xff01;很多小伙伴拿到数据后…

【leetcode题解】链表

目录 链表 两数相加 两两交换链表中的节点 重排链表 合并 K 个升序链表&#xff08;困难&#xff09; K 个一组翻转链表 链表 1. 常用技巧 画图&#xff01;&#xff01;&#xff01;&#xff08;直观形象&#xff0c;便于我们理解&#xff09;引入虚拟“头”节点&#xf…

Windows打开ftp局域网共享

前提是windows已经设置好开机账号密码了&#xff0c;否则教程不适用 第一先打开电脑ftp共享配置 点击保存即可 2.设置要共享到其他电脑的文件路径&#xff08;如果你要共享整个盘你就设置整个盘&#xff0c;如果是共享盘中某文件就设置某文件&#xff0c;这里是某文件&#x…

我爱学算法之——滑动窗口攻克子数组和子串难题(中)

学习算法&#xff0c;继续加油&#xff01;&#xff01;&#xff01; 一、将 x 减到 0 的最小操作数 题目解析 来看这一道题&#xff0c;题目给定一个数组nums和一个整数x&#xff1b;我们可以在数组nums的左边或者右边进行操作&#xff08;x减去该位置的值&#xff09;&#…

从零开始上手huggingface

1. 环境配置 # git 安装&#xff1a;https://git-scm.com/ # git lfs安装&#xff1a;https://git-lfs.com git lfs install # huggingface-cli 安装&#xff1a;https://huggingface.co/docs/hub/index pip install huggingface_hub2. 网站直接下载模型 可能会中断&#xff…

用 pytorch 从零开始创建大语言模型(六):对分类进行微调

用 pytorch 从零开始创建大语言模型&#xff08;六&#xff09;&#xff1a;对分类进行微调 6 微调用于分类6.1 微调的不同类别6.2 准备数据集6.3 创建数据加载器6.4 使用预训练权重初始化模型6.5 添加分类头部6.6 计算分类损失和准确率6.7 在监督数据上微调模型6.8 使用LLM进…

Netty——BIO、NIO 与 Netty

文章目录 1. 介绍1.1 BIO1.1.1 概念1.1.2 工作原理1.1.3 优缺点 1.2 NIO1.2.1 概念1.2.2 工作原理1.2.3 优缺点 1.3 Netty1.3.1 概念1.3.2 工作原理1.3.3 优点 2. Netty 与 Java NIO 的区别2.1 抽象层次2.2 API 易用性2.3 性能优化2.4 功能扩展性2.5 线程模型2.6 适用场景 3. 总…

【Linux】信号:信号保存和处理

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.阻塞信号信号集 02.捕捉信号sigaction可重入函数volatileSIGCHLD 01.阻塞信号 实际执行信号的处理动作称为信号递达&#xff1a;每个信号都有一个默认行为&#xff0c;例如终…

应用权限组列表

文章目录 使用须知位置相机麦克风通讯录日历运动数据身体传感器图片和视频音乐和音频跨应用关联设备发现和连接剪切板文件夹文件(deprecated) 使用须知 在申请目标权限前&#xff0c;建议开发者先阅读应用权限管控概述-权限组和子权限&#xff0c;了解相关概念&#xff0c;再合…