You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Flutter中获取MySQL数据时的构建重试功能?

实现自动重试获取HTML数据的方案

没问题,我帮你调整代码,实现当查询返回空数据时自动重试,直到获取到有效HTML内容的需求。核心思路是给数据请求添加重试逻辑,并结合StatefulWidget来管理请求状态:

修改后的完整代码

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class HtmlWebView extends StatefulWidget {
  final String url;

  const HtmlWebView({Key? key, required this.url}) : super(key: key);

  @override
  State<HtmlWebView> createState() => _HtmlWebViewState();
}

class _HtmlWebViewState extends State<HtmlWebView> {
  late Future<List<Map<String, dynamic>>> _dataFuture;
  final Completer<WebViewController> _controller = Completer<WebViewController>();
  
  // 自定义重试间隔(比如2秒)和最大重试次数
  final Duration _retryDelay = const Duration(seconds: 2);
  final int _maxRetries = 10;

  @override
  void initState() {
    super.initState();
    // 初始化时发起带重试的请求
    _dataFuture = _fetchDataWithRetry();
  }

  // 带重试逻辑的数据请求方法
  Future<List<Map<String, dynamic>>> _fetchDataWithRetry() async {
    int retryCount = 0;
    
    while (retryCount < _maxRetries) {
      try {
        final data = await crud_database.getDatos(widget.url);
        
        // 检查是否获取到有效HTML数据
        if (data.isNotEmpty && data[0]["webhtml"] != null && data[0]["webhtml"].isNotEmpty) {
          return data;
        }
        
        // 数据为空,计数+1后等待重试
        retryCount++;
        print("数据为空,第$retryCount次重试...");
        await Future.delayed(_retryDelay);
      } catch (e) {
        // 请求出错,计数+1后等待重试
        retryCount++;
        print("请求出错: $e,第$retryCount次重试...");
        await Future.delayed(_retryDelay);
      }
    }
    
    // 超过最大重试次数,抛出错误
    throw Exception("已尝试$_maxRetries次,仍无法获取有效数据");
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _dataFuture,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Center(
            child: Text("加载失败:${snapshot.error}"),
          );
        }
        
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return const Center(child: CircularProgressIndicator());
          default:
            // 由于重试逻辑,这里必然拿到有效数据
            return WebView(
              initialUrl: UriData.fromString(
                snapshot.data![0]["webhtml"],
                mimeType: "text/html",
              ).toString(),
              onWebViewCreated: (WebViewController webViewController) {
                _controller.complete(webViewController);
              },
            );
        }
      },
    );
  }
}

关键说明

  • 重试逻辑封装:把数据请求放在_fetchDataWithRetry方法里,用while循环实现自动重试,直到获取到非空的有效HTML内容,或者达到最大重试次数。
  • 状态管理:用StatefulWidget维护请求的Future,确保重试逻辑能正确触发UI更新。
  • 异常处理:捕获请求过程中的异常,出错后也会自动重试,避免单次请求失败就直接显示错误。
  • 可控性:通过_retryDelay和_maxRetries参数,可以自由调整重试间隔和最大重试次数,避免无限循环。

使用方式

你只需要在需要展示WebView的地方,直接使用这个HtmlWebView组件即可:

HtmlWebView(url: "你的目标URL")

内容的提问来源于stack exchange,提问作者Landy Cuadra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:54:26