Flutter:无法使用WorkManager初始化共享首选项。

3
正如标题所说,我正在使用两个插件,workmanagershared preferences。其中,workmanager的部分按照其预期运作,而在shared preferences中出现了错误。
以下是与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)
我尝试了另一个stackoverflow问题中的方法(先前代码示例中的第二种方法),然后就没有抛出错误,但正如那个人所说,它不能持久化数据,因此毫无用处。我还尝试了他建议的其他事情(编辑/android/app/build.gradle),以及其他人建议的许多其他事情,但都没有解决我的问题。
有人知道我该怎么做来解决这个问题吗?

1
目前还没有解决方案,但请查看此链接 https://github.com/fluttercommunity/flutter_workmanager/issues/360 - Marcus
2个回答

3

这是由于shared_preferences实现方式的更改,详见此问题的讨论。

目前,在使用隔离区之前,您可以手动运行插件的Dart注册

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

您需要直接添加 shared_preferences_androidshared_preferences_ios 的依赖项,以使用这些类。


1
我已经完成并且它(几乎)能够正常工作,但我还有一个问题:我在普通代码和workmanager代码中设置的shared_preferences数据彼此不一致。在设备管理器中,我可以查看FlutterSharedPreferences.xml文件,该文件显示了由workmanager使用shared_preferences保存的值。但是在我的普通代码中,如果我想要访问shared_preferences中的值,它们是不同的。(而且我两次都使用了 SharedPreferencesAndroid.registerWith() 进行初始化)你知道如何解决这个问题吗? - Cedric
4
shared_preferences 在 Dart 端缓存了偏好设置。如果您想读取未通过插件类的同一实例进行更改的更改(例如从另一个隔离区域中的单独副本),则必须使用 reload() 方法重新加载。 - smorgan
1
我使用了SharedPreferencesAndroid.registerWith()两次进行初始化,但在非隔离代码中没有这样做的必要。 - smorgan
@aaronvargas 这是可以预料的;这些版本是在添加Dart实现之前的版本(这就是在隔离中不自动工作并需要手动调用的部分)。如果您使用这些版本,您本来就不应该遇到此处描述的问题。 - smorgan
3
@smorgan,我尝试过了,但是出现了“PlatformException (PlatformException(channel-error, Unable to establish connection on channel., null, null))”的错误。你有解决方法吗? - stranger_cool
2
嗨@smorgan,我有同样的问题,在我的情况下,只是缺少在AppDelegate.swift中注册插件。https://github.com/fluttercommunity/flutter_workmanager/blob/main/IOS_SETUP.md#registered-plugins - isaacfi

0

我遇到了同样的问题,错误信息是:

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)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接