Flutter网络缓存拦截插件network_cache_interceptor的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter网络缓存拦截插件network_cache_interceptor的使用

Network Cache Interceptor 是一个为缓存网络请求而设计的自定义Dio拦截器。它在离线时返回缓存的数据,并优化了网络请求处理。

📦 安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  network_cache_interceptor: ^1.2.4

或者使用命令行工具安装:

flutter pub add network_cache_interceptor

🚀 新版本特性(1.2.4)

  • 更新缓存逻辑:所有GET请求现在默认被缓存,即使显式指定了 cache: false。这确保了缓存的一致性,同时通过额外选项提供手动控制。

🚀 使用方法

1. 配置 Dio

首先需要配置Dio实例并添加拦截器:

import 'package:dio/dio.dart';
import 'package:network_cache_interceptor/network_cache_interceptor.dart';

void main() {
  final dio = Dio();

  // 添加拦截器
  dio.interceptors.add(
    NetworkCacheInterceptor(
      noCacheStatusCodes: [401, 403],  // 不缓存的状态码
      cacheValidityMinutes: 30,        // 缓存有效时间(分钟)
      getCachedDataWhenError: true,    // 网络错误时获取缓存数据
    ),
  );
}

2. 发起请求

所有GET请求默认会被缓存,但你可以通过 extra['cache'] 覆盖缓存行为:

final response = await dio.get(
  'https://jsonplaceholder.typicode.com/posts',
  options: Options(
    extra: {
      'cache': true,         // 显式启用缓存
      'validate_time': 60,   // 缓存有效时间(分钟)
    },
  ),
);

禁用缓存:

final response = await dio.get(
  'https://jsonplaceholder.typicode.com/posts',
  options: Options(
    extra: {'cache': false}, // 禁用缓存
  ),
);

3. 清除缓存数据

清除数据库中的所有缓存数据:

final cacheInterceptor = NetworkCacheInterceptor();
await cacheInterceptor.clearDatabase();

⚙️ 配置参数

参数 描述 默认值
noCacheStatusCodes 不缓存的状态码 [401, 403]
cacheValidityMinutes 缓存有效时间(分钟) 30
getCachedDataWhenError 网络错误时获取缓存数据 true

🔧 技术细节

  • 缓存逻辑:如果发生网络问题,会自动返回可用的缓存响应。
  • 错误日志:所有错误都会通过 log() 记录。
  • 数据存储:数据使用SQL数据库本地保存。

🎯 示例代码

完整的示例应用:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:network_cache_interceptor/network_cache_interceptor.dart';

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

class MyApp extends StatelessWidget {
  final Dio dio = Dio()..interceptors.add(NetworkCacheInterceptor());

  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Network Cache Example'),
        ),
        body: Center(
          child: FutureBuilder(
            future: fetchData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return const CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return Text('Data: ${snapshot.data}');
              }
            },
          ),
        ),
      ),
    );
  }

  Future<String> fetchData() async {
    try {
      final response = await dio.get(
        'https://jsonplaceholder.typicode.com/posts/1',
        options: Options(
          extra: {
            'cache': true,
            'validate_time': 60, // 缓存有效时间(分钟)
          },
        ),
      );
      return response.data.toString();
    } catch (e) {
      return 'Failed to fetch data';
    }
  }
}

这个示例展示了如何在一个Flutter应用中使用 network_cache_interceptor 来缓存网络请求并在UI上显示结果。希望这些信息对你有帮助!


更多关于Flutter网络缓存拦截插件network_cache_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络缓存拦截插件network_cache_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 network_cache_interceptor 插件在 Flutter 中实现网络请求缓存的示例代码。network_cache_interceptor 是一个强大的插件,它允许你拦截 HTTP 请求并缓存响应,从而加速应用并提高用户体验。

首先,确保你的 pubspec.yaml 文件中包含了 network_cache_interceptor 依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.0
  network_cache_interceptor: ^3.0.0

然后,运行 flutter pub get 来获取依赖。

接下来,你可以按照以下步骤配置和使用 network_cache_interceptor

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:network_cache_interceptor/network_cache_interceptor.dart';
import 'dart:io';
  1. 配置 Dio 实例和缓存拦截器
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late Dio _dio;

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

  void setUpDio() async {
    // 设置缓存存储位置(这里使用内存缓存作为示例,你也可以使用文件系统)
    final cacheStore = InMemoryCacheStore();

    // 配置缓存拦截器
    final cacheInterceptor = CacheInterceptor(
      cacheStore: cacheStore,
      maxStale: Duration(days: 7), // 最大陈旧时间
      maxAge: Duration(hours: 1),  // 最大有效时间
    );

    // 创建 Dio 实例并添加拦截器
    _dio = Dio(
      BaseOptions(
        baseUrl: 'https://api.example.com', // 替换为你的API基础URL
      ),
    )..interceptors.add(cacheInterceptor);

    // 可选:添加日志拦截器以便调试
    _dio.interceptors.add(LogInterceptor(
      responseBody: true,
      requestBody: true,
      requestHeader: true,
      responseBodyPrettyPrint: true,
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Network Cache Interceptor Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            fetchData();
          },
          child: Text('Fetch Data'),
        ),
      ),
    );
  }

  Future<void> fetchData() async {
    try {
      Response response = await _dio.get('/path/to/your/endpoint');
      print('Data: ${response.data}');
    } catch (e) {
      print('Error: $e');
    }
  }
}

在上面的代码中,我们:

  1. 导入了必要的包。
  2. 创建了一个 Dio 实例,并为其添加了 CacheInterceptor
  3. 配置了缓存存储为内存存储(你也可以使用文件系统存储)。
  4. 配置了缓存的最大陈旧时间和最大有效时间。
  5. 添加了一个日志拦截器以便调试(可选)。
  6. 创建了一个按钮,点击按钮时会发起网络请求。

这样,当你第一次请求数据时,数据会被缓存。在缓存有效期内再次请求相同的数据时,将直接从缓存中获取,而不是再次发起网络请求。

请注意,这只是一个基本的示例。在实际应用中,你可能需要根据你的需求调整缓存策略、处理错误情况,以及优化用户体验。

回到顶部