flutter_background_service_Android插件在安卓设备抛出主隔离区使用异常
Flutter后台服务集成flutter_background_service_Android后异常问题
我正在开发一款使用flutter_background_service包实现后台服务的Flutter应用,集成flutter_background_service_Android插件后,安卓设备上的后台服务无法正常运行,抛出如下异常:
flutter_background_service_android threw an error: Exception: This class should only be used in the main isolate (UI App). The app may not function as expected until you remove this plugin from pubspec.yaml
以下是我的后台服务实现代码(my_background_service.dart):
// ignore_for_file: avoid_print import 'dart:async'; import 'dart:io'; import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:flutter_background_service_android/flutter_background_service_android.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '/helper/my_helper/socket_io_helper.dart'; import '/helper/my_helper/my_get_di.dart' as my_di; /// Initialization of the Background Service Future<void> initializeBackgroundService() async { final service = FlutterBackgroundService(); /// OPTIONAL, using custom notification channel id const AndroidNotificationChannel channel = AndroidNotificationChannel( 'my_foreground', 'MY FOREGROUND SERVICE', description: 'This channel is used for important notifications.', importance: Importance.low, ); /// Object of the FlutterLocalNotificationsPlugin final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); /// Initialize settings if (Platform.isIOS || Platform.isAndroid) { await flutterLocalNotificationsPlugin.initialize( const InitializationSettings( iOS: DarwinInitializationSettings(), android: AndroidInitializationSettings('ic_bg_service_small'), ), ); } /// Create android notification channel await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); /// Configuration of the Background Service await service.configure( androidConfiguration: AndroidConfiguration( onStart: onStart, autoStart: true, isForegroundMode: true, notificationChannelId: 'my_foreground', initialNotificationTitle: 'AWESOME SERVICE', initialNotificationContent: 'Initializing', foregroundServiceNotificationId: 888, ), iosConfiguration: IosConfiguration( autoStart: true, onForeground: onStart, onBackground: onIosBackground, ), ); /// Starting the background service after doing the configurations service.startService(); } // DOLATER: Handle the iOS Background Task Here @pragma('vm:entry-point') Future<bool> onIosBackground(ServiceInstance service) async { WidgetsFlutterBinding.ensureInitialized(); DartPluginRegistrant.ensureInitialized(); return true; } @pragma('vm:entry-point') void onStart(ServiceInstance service) async { DartPluginRegistrant.ensureInitialized(); /// OPTIONAL when use custom notification final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); if (service is AndroidServiceInstance) { service.on('setAsForeground').listen((event) { service.setAsForegroundService(); }); service.on('setAsBackground').listen((event) { service.setAsBackgroundService(); }); } service.on('stopService').listen((event) { service.stopSelf(); }); /// My instances SocketIoHelper socketIoHelper = SocketIoHelper(); /// Executed when the app is in the foreground service.on('loginSuccess').listen((event) async { /// Creating a socket.io client await my_di.init(); await socketIoHelper.initializeAwesomeNotification(); await socketIoHelper.initializeMsgService(); await socketIoHelper.createTopics(); }); service.on('containsTheTopics').listen((event) async { await socketIoHelper.joinCallInitializationTopic(); await socketIoHelper.listenCallInitializationTopic(); await socketIoHelper.listenCallRecieveTopic(); }); /// Executed when the app is in the background final prefs = await SharedPreferences.getInstance(); final plusRemovedPhoneNumberFromLocal = prefs.getString("plusRemovedPhoneNumber") ?? ""; /// Creating a socket.io client if (plusRemovedPhoneNumberFromLocal != "") { await my_di.init(); await socketIoHelper.initializeAwesomeNotification(); await socketIoHelper.initializeMsgService(); await socketIoHelper.joinCallInitializationTopic(); await socketIoHelper.listenCallInitializationTopic(); await socketIoHelper.listenCallRecieveTopic(); } /// Update the background service timer /// And show it as a foreground notification Timer.periodic(const Duration(seconds: 1), (timer) async { if (service is AndroidServiceInstance) { if (await service.isForegroundService()) { flutterLocalNotificationsPlugin.show( 888, 'COOL SERVICE', 'Awesome ${DateTime.now()}', const NotificationDetails( android: AndroidNotificationDetails( 'my_foreground', 'MY FOREGROUND SERVICE', icon: 'ic_bg_service_small', ongoing: true, ), ), ); /// if you don't using custom notification, uncomment this service.setForegroundNotificationInfo( title: "My Service", content: "", ); } } /// Printing background service timer in the flutter terminal print( "📗 Background Service ====> ${DateFormat('yyyy-MM-dd hh:mm:ss').format(DateTime.now())} 📗"); }); }
问题原因与解决方案
原因
异常提示明确说明flutter_background_service_Android的类只能在**主隔离(UI线程)**中使用,而你的后台服务入口函数onStart被标记为@pragma('vm:entry-point'),运行在单独的后台隔离中,在此环境下加载该插件的类会触发异常。
解决步骤
移除后台服务代码中的插件导入
从my_background_service.dart中删除以下导入语句:import 'package:flutter_background_service_android/flutter_background_service_android.dart';你代码中用到的
AndroidServiceInstance类型判断属于flutter_background_service核心包的功能,不需要额外导入flutter_background_service_Android即可使用。确认插件仅在主隔离中使用
如果需要调用flutter_background_service_Android提供的扩展API(比如高级安卓后台配置),确保这些代码只在主隔离(UI层)执行,不要放到后台服务的onStart函数中。重新运行项目
移除导入后重新编译运行,后台服务即可正常启动。
内容的提问来源于stack exchange,提问作者Chanaka
相关产品推荐
相关产品推荐

