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

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

目录

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

一、简单介绍

二、connectivity_plus

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

[2、使用 connectivity_plus 的注意事项](#2、使用 connectivity_plus 的注意事项)

[三、安装 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 添加

Dart 复制代码
dependencies:
  connectivity_plus: ^6.1.3

四、简单效果

五、简单案例实现

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

2、创建一个 application 的 Flutter 项目

3、项目结构如下

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

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

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

六、关键代码

1、NetworkStatusManager

Dart 复制代码
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

Dart 复制代码
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 中显示当前的网络连接类型。

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

相关推荐
ThinkPet3 小时前
【005安卓开发方案调研】之Flutter+Dart技术开发安卓
android·flutter·跨平台·dart
月明泉清6 小时前
flutter doctor提示cmdline-tools component is missing错误的解决
flutter
爱学习的大牛12315 小时前
如何在 Flutter 中使用 WebRTC
flutter·webrtc
米心18 小时前
Flutter 快速接入Fair
flutter
leluckys18 小时前
flutter 专题 九十 四 Flutter开发之基础知识
flutter
消失的旧时光-194318 小时前
浅谈跨平台框架的演变(H5混合开发->RN->Flutter)
android·开发语言·flutter·react native·跨平台
Nathan202406161 天前
Flutter - 基础组件的内容及框架
flutter
Zsnoin能1 天前
3分钟实现git托管软件安装包,并实现版本检测和更新功能
git·flutter
Nathan202406161 天前
Dart - 基本语法与Kotlin的对比
android·flutter·面试