确保在后台处理 flutter 应用程序中的 REST 调用

Ensure processing of a REST call in flutter app in background

我需要确保某个 HTTP 请求已成功发送。因此,我想知道是否有一种简单的方法可以将这样的请求转移到后台服务任务中。

我的问题背景如下: 我们正在使用 flutter 开发一个调查应用程序。不幸的是,该应用程序旨在在无法保证移动互联网连接的环境中使用。因此,我无法简单地 post 一次调查结果,但如果由于网络问题而失败,我必须重试。我当前的代码如下所示。我当前解决方案的问题是它只能在应用程序一直处于活动状态时工作。如果用户最小化或关闭应用程序,我要上传的数据就会丢失。 因此,我正在寻找一种将上传过程包装在后台服务任务中的解决方案,以便即使用户关闭应用程序也能处理它。我找到了几个 post 和插件(即 https://medium.com/flutter-io/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124 and https://pub.dartlang.org/packages/background_fetch),但它们对我的特定用例没有帮助。第一个描述了当特定事件(即地理围栏发生)时如何通知应用程序的方式,第二个仅每 15 分钟工作一次,并且也关注不同的场景。 有人知道一种简单的方法,我如何确保即使在互联网连接不佳(甚至 none 目前)的情况下也能处理请求,同时允许用户最小化甚至关闭应用程序?

Future _processUploadQueue() async {
  int retryCounter = 0;
  Future.doWhile(() {
    if(retryCounter == 10){
      print('Abborted after 10 tries');
      return false;
    }
    if (_request.uploaded) {
      print('Upload ready');
      return false;
    }
    if(! _request.uploaded) {
      _networkService.sendRequest(request: _request.entry)
          .then((id){
            print(id);
            setState(() {
              _request.uploaded = true;
            });
      }).catchError((e) {
        retryCounter++;
        print(e);
      });
    }
    // e ^ retryCounter, min 0 Sec, max 10 minutes
    int waitTime = min(max(0, exp(retryCounter)).round(), 600);
    print('Waiting $waitTime seconds till next try');
    return new Future.delayed(new Duration(seconds: waitTime), () {
      print('waited $waitTime seconds');
      return true;
    });
  })
  .then(print)
  .catchError(print);
}

您可以使用插件 shared_preferences 将每个 HTTP 响应保存到设备,直到上传成功完成。像这样:

requests: [
  {
    id: 8eh1gc,
    request: "..."
  },
  ...
],

然后每当应用程序启动时,检查列表中是否有任何请求,重试它们,如果完成则删除它们。您也可以使用 background_fetch 每 15 分钟执行一次此操作。