gpt4 book ai didi

flutter - 如何在 Isolate 上实例化本地通知?

转载 作者:行者123 更新时间:2023-12-03 02:47:33 32 4
gpt4 key购买 nike

我的问题的背景:我正在开发一个 Flutter 应用程序,它每隔几个小时执行一次重复的后台事件,并在有任何更新时通知用户。

目前,我已经创建了一个能够执行后台事件的隔离功能(但目前尚未安排),并且我正在使用 flutter_local_notifications 包在本地生成通知。

这是我的代码:

调用isolate函数的piece-

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)

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

最佳答案

您可以使用一个名为 flutter_isolate 的包.根据它的描述,它允许在新的 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 的 flutter 生成文件自动注册所有插件(在 Android 上。我不知道如何它适用于 iOS)。但是 github(herehere)上有一些关于插件无法正常工作的问题。因此,根据软件包创建者的说法,您可以复制此文件并创建一个自定义插件注册者,在启动新的 FlutterIsolate 时删除不需要的插件。然后,在您的 MainActivity 文件中,从 FlutterIsolatePlugin 调用方法 setCustomIsolateRegistrant

例如:

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

请记住,我不了解 native 代码在 Android 上的工作方式。这个例子的灵感来自于我提到的一个问题的答案。所以,我不确定这个例子是否有效,甚至是否正确,但这是原则,我认为这是一个有用的信息。希望对您有所帮助。

关于flutter - 如何在 Isolate 上实例化本地通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58926953/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com