【问题标题】:Flutter: can't initialize shared preferences with workmanagerFlutter:无法与 workmanager 初始化共享首选项
【发布时间】:2023-02-13 22:29:18
【问题描述】:

正如标题所说,我正在使用 2 个插件,workmanagershared preferences。 Workmanager 部分按预期工作,而我从共享首选项中收到错误。

这是我的代码的一部分,它与 workmanager 插件有关:

void callbackDispatcher() {
  Workmanager().executeTask((taskName, inputData) async {
    switch (taskName) {
      case 'midnight_task':
        try {
          await SharedPrefsHelper().initSharedPrefsInstance(); //THIS line causes the error
          await PedometerService.midnightTask();
          print('workmanager_service.dart: looks like midnightTask got successfully executed :D');
        } catch (e) {
          print('workmanager_service.dart midnightTask error: $e');
        }
        break;
      default:
        print('workmanager_service.dart callbackDispatcher(): unhandled taskName: $taskName');
    }
    return Future.value(true); // "The task is successful"
  });
}

这是我处理共享首选项的代码的一部分:

SharedPreferences _prefs;

  Future<void> initSharedPrefsInstance() async {
    print('initSharedPrefsInstance()');
    if (_prefs == null) _prefs = await SharedPreferences.getInstance(); //the error gets thrown here
    print('shared prefs initialized()');
  }

  
  //this will NOT persist data
  Future<void> initSharedPrefsInstanceMock() async {
    print('initSharedPrefsInstanceMock()');
    SharedPreferences.setMockInitialValues({}); //<- this line: only difference to above method
    if (_prefs == null) _prefs = await SharedPreferences.getInstance();
    print('initSharedPrefsInstanceMock: shared prefs initialized()');
  }

在注释指定的行抛出以下错误: workmanager_service.dart midnightTask error: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)

我试过 this from another stackoverflow question(前面代码示例中的第二种方法),然后它不会抛出错误,但正如那个人所说,它不会持久保存数据,所以它没用。我还尝试了他建议的其他事情(编辑/android/app/build.gradle),以及其他人建议的许多其他事情,但对我没有任何帮助。

有谁知道我能做些什么来解决这个问题?

【问题讨论】:

标签: flutter background sharedpreferences android-workmanager flutter-workmanager


【解决方案1】:

这是由于shared_preferences 的实现发生了变化,请参阅this issue 进行讨论。

现在你可以manually run the plugin's Dart registration 在隔离中使用它之前:

if (Platform.isAndroid) SharedPreferencesAndroid.registerWith();
if (Platform.isIOS) SharedPreferencesIOS.registerWith();

您需要添加对 shared_preferences_androidshared_preferences_ios 的直接依赖才能使用这些类。

【讨论】:

  • 我这样做了,它(几乎)起作用了,但我有一个问题:我在 shared_preferences 中从我的普通代码和我的 workmanager 代码中设置的数据彼此不一致。在设备管理器中,我可以查看文件 FlutterSharedPreferences.xml,它似乎显示了 workmanager 使用 shared_preferences 保存的值。但是在我的普通代码中,如果我想从 shared_preferences 访问值,它们是不同的。 (我使用 SharedPreferencesAndroid.registerWith(); 两次初始化)你知道如何解决这个问题吗?
  • @Cedric shared_preferences 在 Dart 端缓存首选项。如果你想读取不是通过插件类的同一个实例所做的更改(比如从另一个隔离中的单独副本),你必须reload()
  • “我使用 SharedPreferencesAndroid.registerWith(); 两次进行初始化” -> 没有理由在非隔离代码中执行此操作。
  • @smorgan 我试过了但是我有关于'PlatformException (PlatformException(channel-error, Unable to establish connection on channel., null, null))'的错误。你知道如何解决这个问题吗?
  • 嗨@smorgan,我有同样的问题,在我的情况下只是缺少在 AppDelegate.swift 中注册插件 github.com/fluttercommunity/flutter_workmanager/blob/main/…
【解决方案2】:

我有同样的问题,错误是:

PlatformException(channel-error, Unable to establish connection on channel., null, null)

要解决它,您应该更新 ios/Runner/AppDelegate.swift:

https://github.com/fluttercommunity/flutter_workmanager/blob/main/IOS_SETUP.md#registered-plugins

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // ...
    
    WorkmanagerPlugin.setPluginRegistrantCallback {
        registry in GeneratedPluginRegistrant.register(with: registry)
    }
    
    WorkmanagerPlugin.registerTask(withIdentifier: "your_task_identifier")
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-15
    • 2022-11-25
    • 2021-12-31
    • 2021-09-04
    • 1970-01-01
    • 2022-01-23
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多