【问题标题】:Initialize Dio with persistent cookie at the start of the program在程序开始时使用持久 cookie 初始化 Dio
【发布时间】:2021-11-13 04:57:27
【问题描述】:

我在我的应用程序中使用 Dio,我希望它保存 cookie。事实证明,我必须下载三个额外的包才能做到这一点:cookie_jar、dio_cookie_manager 和 path_provider。

我需要:

  1. 获取申请文件目录: Directory docDir = await getApplicationDocumentsDirectory();

  2. 将其传递给 PersistCookieJar PersistCookieJar(storage: FileStorage(appDocDir.path + '/.cookies/'));

  3. 并将其添加到拦截器中: dio.interceptors.add(CookieManager(_cookieJar));

我的问题是第一部分。出于某种原因,getApplicationDocumentsDirectory(); 在 StatefulWidget 小部件中未使用时会引发错误。

我有两个问题:

  1. 到底为什么要获取路径需要 StatefulWidget?
  2. 我怎样才能做我想做的事?我需要尽早初始化 Dio,以便在加载 UI 时,用户已经(或几乎)登录。另外,我不想将启动客户端对象的逻辑放在 UI 代码中,例如,这可能会导致它在创建小部件时多次启动。

我的代码现在的样子:

Future<void> initStuff() async {
  initLocator();

  Directory docDir = await getApplicationDocumentsDirectory(); // throws
  print('docDir = ${docDir.path}');
  Client cli = Client(docDir);
  locator.registerSingleton<Client>(cli);

  // ...
}

void main() async {
  await initStuff();

  runApp(MyApp());
}

客户端构造函数:

  Client(Directory appDocDir) {
    final _cookieJar = PersistCookieJar(storage: FileStorage(appDocDir.path + '/.cookies/'));

    dio = Dio()
      ..options.baseUrl = Utils.SERVER_ADDRESS
      ..options.sendTimeout = 5000
      ..options.receiveTimeout = 5000
      ..options.connectTimeout = 5000
      ..interceptors.add(CookieManager(_cookieJar));
  }

我得到的错误:

E/flutter (24953): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value
E/flutter (24953): #0      MethodChannel.binaryMessenger
package:flutter/…/services/platform_channel.dart:142
E/flutter (24953): #1      MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:148
E/flutter (24953): #2      MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:331
E/flutter (24953): #3      MethodChannelPathProvider.getApplicationDocumentsPath
package:path_provider_platform_interface/src/method_channel_path_provider.dart:50
E/flutter (24953): #4      getApplicationDocumentsDirectory
package:path_provider/path_provider.dart:138
E/flutter (24953): #5      initStuff
package:proj/main.dart:20
E/flutter (24953): #6      main
package:proj/main.dart:63
E/flutter (24953): #7      _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:142:25)
E/flutter (24953): #8      _rootRun (dart:async/zone.dart:1354:13)
E/flutter (24953): #9      _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter (24953): #10     _runZoned (dart:async/zone.dart:1789:10)
E/flutter (24953): #11     runZonedGuarded (dart:async/zone.dart:1777:12)
E/flutter (24953): #12     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:138:5)
E/flutter (24953): #13     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
E/flutter (24953): #14     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

【问题讨论】:

  • 问:为什么获取路径需要 StatefulWidget? A:因为你隐式地写了可变数据?问:我很好奇:可以请Edit 您的帖子并复制/粘贴实际的错误消息吗?这将是非常有帮助的!
  • @paulsm4 添加了错误
  • @paulsm4 “因为你隐式地写入了可变数据?” - 我想我只是认为这样的东西与业务逻辑更相关。您放入自己的一组类/函数中的东西,然后您可以从 UI 调用。再加上对 StatelefullWidget 的需求,使得包的通用性降低

标签: flutter dart dio


【解决方案1】:

好的:感谢您更新您的帖子。

错误是:Unhandled Exception: Null check operator used on a null value

它来自第 3 方库调用 getApplicationDocumentsDirectory(),它的发生是因为您正在调用启用了 null 安全性的(当前未初始化的)值(一件好事!)。

建议:

  1. 使用 StatefulWidget 需要做更多的工作 - 但在这里很有意义。它也恰好为您解决了问题,对吗?

  2. 您可以尝试使 docDir 为空(例如 String? path)。这正是 getApplicationDocument 页面显示的内容:

https://pub.dev/documentation/path_provider/latest/path_provider/getApplicationDocumentsDirectory.html

Future<Directory> getApplicationDocumentsDirectory() async {
  final String? path = await _platform.getApplicationDocumentsPath();
  if (path == null) {
    throw MissingPlatformDirectoryException(
        'Unable to get application documents directory');
  }
  return Directory(path);
}
  1. 最后,查看这些链接:

【讨论】:

  • 感谢您的建议!使docDir 可以为空并不能解决问题,所以我将尝试将它放入StatefulWidget。我还没有这样做;我刚刚在另一个 SO question 中了解到这一点,并犹豫是否这样做,因为我希望有更好的方法(也许有一个不同的库?)
  • 实际上,我知道“StatefulWidget”是否会对这个特定问题产生任何影响。我以为你说你已经尝试过了,而且它对你有用。如果不是这样不是...那么无论如何,请先尝试我的其他建议。这是一篇关于 Flutter“有状态”与“无状态”小部件的好文章:geeksforgeeks.org/flutter-stateful-vs-stateless-widgets。您的大多数小部件可能是“无状态的”......但重要的是要根据需要同时使用两者。
  • 它现在可以在 Stateful 中工作。我目前正在弄清楚为什么持久 cookie jar 不保存 cookie,但这无关
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 2016-03-09
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多