首页 > 解决方案 > 在初始化绑定之前访问了 ServicesBinding.defaultBinaryMessenger 的特殊情况

问题描述

我正在我的 Flutter 应用程序的 initState() 中运行一个执行 oneSignal 初始化的方法

此方法的一部分是将用户的标签发送到 OneSignal Api 但根据他们的文档

他们说这种发送标签的方法大约需要 5 秒,所以建议不要阻止其他任务

所以我决定在一个新生成的隔离中运行它,但我收到了这个错误消息

Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter ( 2679): 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 ( 2679): 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.

即使在 runApp(myApp()) 之前的 main 方法中运行以下方法后,我仍然收到相同的错误消息

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  setup();
  bool isAcademic = HelperFucntions.isAcademic(await UserCachedInfo().getRecord('account_type'));
  runApp(MyApp(isAcademic));
}

这是我想在新的隔离中运行它的方法

_handleOneSignalRegistration(String d)async{
  String userId;
  while (userId == null) {
    var data = await OneSignal.shared.getPermissionSubscriptionState();
    userId = data.subscriptionStatus.userId;
    if (userId != null) {
      print('*******************************************************************');
      print('we got it inside while loop => $userId');
      await CachingServices.saveStringField(key: 'one_signal_id', value: userId);
      print('************************************************************************');

      print('===================================== fetching tags');
      final Map<String,dynamic> myTags = await OneSignal.shared.getTags();
      print(myTags);
//          final Map<String,dynamic> tags = await HelperFucntions.getUserTags();
//          if(tags != null){
//            OneSignal.shared.sendTags(tags);
//          }
    }
  }
}

这是我在 initState 方法中调用的初始化方法

  Future<void> initialize() async {
    if (_isInitialized) {
      return;
    }
    LocalNotificationService localNotificationService = LocalNotificationService.getInstance();
    await localNotificationService.initialize();

    OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);

    OneSignal.shared.init(
      ONE_SIGNAL_ID,
      iOSSettings: {OSiOSSettings.autoPrompt: false, OSiOSSettings.inAppLaunchUrl: false},
    );
    OneSignal.shared.setInFocusDisplayType(OSNotificationDisplayType.none);



// The promptForPushNotificationsWithUserResponse function will show the iOS push notification prompt. We recommend removing the following code and instead using an In-App Message to prompt for notification permission
    await OneSignal.shared.promptUserForPushNotificationPermission(fallbackToSettings: true);

    WidgetsFlutterBinding.ensureInitialized();
    // this will spawn an Isolate so in order not to block the main isolate
    compute(_handleOneSignalRegistration,'d');
    OneSignal.shared.setNotificationReceivedHandler(
      (OSNotification notification) {
        print(++_channelID);
        NotificationStateProvider notificationStateProvider = locator.get<NotificationStateProvider>();
        var receivedNotification;
        try {
          receivedNotification = new NotificationInstance(
            title: notification.payload.title,
            body: notification.payload.body,
            id: notification.payload.notificationId,
            sentAt: DateTime.fromMillisecondsSinceEpoch(notification.payload.rawPayload['google.sent_time']),
          );
          notificationStateProvider.addToNotificationsList(receivedNotification);
        } catch (err) {
          throw err;
        }

      },
    );
    _isInitialized = true;
  }

标签: flutterdart-isolates

解决方案


推荐阅读