如何在隔离上实例化本地通知?

我的问题背景:我正在开发Flutter应用,该应用每隔几个小时执行一次重复的后台活动,并通知用户是否有任何更新。

当前,我创建了一个隔离函数,该函数能够执行后台活动(但当前尚未安排),并且我正在使用flutter_local_notifications包在本地生成通知。

这是我的代码:

调用隔离功能的部分-

Future<void> executeBgUpdate() async {
  Completer c = Completer();

  ProductManager.close();
  Hive.close();
  Future f = compute(_isolateUpdateFunction,SharedVariables.appDocsDirPath); // See next block for code

  f.then((value) async {
    await init.db();
    c.complete(value);
  });

  return c.future;
}

隔离功能-

Future<void> _isolateUpdateFunction(String appDataDirPath) async {
  Completer c = Completer();

  try {
    await init.logger();
    await init.db(appDocsDirPath: appDataDirPath);
    Notifier.init(); // See next block for code

    // Background Task goes here

    await Future.wait(futures);

    Notifier.showNotification();

    ProductManager.close();
    Hive.close();
  } catch (ex,stacktrace) {
    SharedInstances.logger.e("Failed in BG Update Isolate!",ex,stacktrace);
  }

  c.complete(null);
  return c.future;
}

Notifier.init()-

的内容
static FlutterLocalNotificationsPlugin _notifier;

  static void init() {
    _notifier = new FlutterLocalNotificationsPlugin();

    var initializationSettingsAndroid =
    new AndroidInitializationSettings('@mipmap/ic_launcher');

    var initializationSettingsIOS = new IOSInitializationSettings(
        onDidReceiveLocalNotification: null);

    var initializationSettings = new InitializationSettings(
        initializationSettingsAndroid,initializationSettingsIOS);

    _notifier.initialize(initializationSettings,onSelectNotification: null);
  }

我得到的例外是:

E/flutter (30954): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter (30954): If you're running an application and need to access the binary messenger before `runApp()` has been called (for example,during plugin initialization),then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
E/flutter (30954): If you're running a test,you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.
E/flutter (30954): #0      defaultBinaryMessenger.<anonymous closure> (package:flutter/src/services/binary_messenger.dart:73:7)
E/flutter (30954): #1      defaultBinaryMessenger (package:flutter/src/services/binary_messenger.dart:86:4)
E/flutter (30954): #2      MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:140:62)
E/flutter (30954): #3      MethodChannel.setMethodCallHandler (package:flutter/src/services/platform_channel.dart:368:5)
E/flutter (30954): #4      FlutterLocalNotificationsPlugin.initialize (package:flutter_local_notifications/src/flutter_local_notifications.dart:94:14)
E/flutter (30954): <asynchronous suspension>

如果在隔离器中初始化通告程序之前将WidgetsFlutterBinding.ensureInitialized()添加到,则会出现此异常-

error: native function 'Window_setNeedsReportTimings' (2 arguments) cannot be found

// StackTrace:
I/flutter (  433): │ #0      Window.onReportTimings= (dart:ui/window.dart:964:7)
I/flutter (  433): │ #1      SchedulerBinding.addTimingsCallback (package:flutter/src/scheduler/binding.dart:230:14)
I/flutter (  433): │ #2      SchedulerBinding.initInstances (package:flutter/src/scheduler/binding.dart:206:7)
I/flutter (  433): │ #3      PaintingBinding.initInstances (package:flutter/src/painting/binding.dart:21:11)
I/flutter (  433): │ #4      SemanticsBinding.initInstances (package:flutter/src/semantics/binding.dart:22:11)
I/flutter (  433): │ #5      RendererBinding.initInstances (package:flutter/src/rendering/binding.dart:29:11)
I/flutter (  433): │ #6      WidgetsBinding.initInstances (package:flutter/src/widgets/binding.dart:253:11)
I/flutter (  433): │ #7      new BindingBase (package:flutter/src/foundation/binding.dart:56:5)
I/flutter (  433): │ #8      new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #9      new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #10     new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #11     new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #12     new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #13     new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #14     new _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #15     new WidgetsFlutterBinding (package:flutter/src/widgets/binding.dart)
I/flutter (  433): │ #16     WidgetsFlutterBinding.ensureInitialized (package:flutter/src/widgets/binding.dart:1083:7)

我对应该如何进行一无所知。任何帮助都会很棒,谢谢!

langku 回答:如何在隔离上实例化本地通知?

有一个名为flutter_isolate的软件包可以使用。根据其描述,它允许在新的隔离中使用flutter插件。我将其与flutter_ffmpegsqflite一起使用,并且可以正常工作。当我尝试不使用此软件包而使用它们时,我收到了相同的错误。

flutter_isolate软件包添加到pubspec.yaml后,而不是

Future f = compute(_isolateUpdateFunction,SharedVariables.appDocsDirPath);

您可以使用

Future f = FlutterIsolate.spawn(_isolateUpdateFunction,SharedVariables.appDocsDirPath);

该软件包将使用app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java(在Android上,不知道如何在iOS上运行)使用flutter生成的文件自动注册所有插件。但是在github(herehere)上存在一些关于插件无法正常工作的问题。因此,根据软件包创建者的说法,您可以复制此文件并创建自定义插件注册者,从而在启动新的FlutterIsolate时删除不需要的插件。然后,在您的MainActivity文件中,从setCustomIsolateRegistrant调用方法FlutterIsolatePlugin

例如:

public final class IsolatePluginRegistrant {
  public static void registerWith(@NonNull FlutterEngine flutterEngine) {
    ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine);
    com.arthenica.flutter.ffmpeg.FlutterFFmpegPlugin
      .registerWith(shimPluginRegistry.registrarFor("com.arthenica.flutter.ffmpeg.FlutterFFmpegPlugin"));
  }
}
public class MainActivity extends FlutterActivity {
  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    FlutterIsolatePlugin.setCustomIsolateRegistrant(IsolatePluginRegistrant.class);
    super.onCreate(savedInstanceState);
  }
}

请记住,我不了解本地代码如何在Android上工作。这个例子的灵感来自我提到的其中一个问题。因此,我不确定该示例是否有效,甚至是正确的,但这是原理,我认为这是有用的信息。希望对您有所帮助。

本文链接:https://www.f2er.com/3076243.html

大家都在问