APP更新后启动崩溃:FlutterCallbackInformation为空致WorkManager异常
Flutter workmanager ^0.8.0 后台任务触发时NullPointerException问题修复
问题场景
使用workmanager: ^0.8.0插件执行后台同步任务,生产环境用户更新APP后触发后台任务时出现崩溃,重装APP后崩溃消失。崩溃核心表现为:
DartExecutor$DartCallback.toString()中出现NullPointerException
错误日志
Exception java.lang.NullPointerException: Attempt to read from field 'java.lang.String io.flutter.view.FlutterCallbackInformation.callbackLibraryPath' on a null object reference in method 'java.lang.String io.flutter.embedding.engine.dart.DartExecutor$DartCallback.toString()' at io.flutter.embedding.engine.dart.DartExecutor$DartCallback.toString (DartExecutor.java:426) at java.lang.String.valueOf (String.java:4112) at java.lang.StringBuilder.append (StringBuilder.java:179) at io.flutter.embedding.engine.dart.DartExecutor.executeDartCallback (DartExecutor.java:181)
修复方案及代码实现
针对更新后旧任务残留、初始化顺序等问题,实施了以下修复:
1. 强化后台任务调度器的空安全与初始化稳定性
给callbackDispatcher添加严格的空安全检查,确保Flutter绑定、依赖初始化的容错性:
@pragma('vm:entry-point') void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { // 任务空检查 if (task.isEmpty) { 'Background task is null or empty'.logs(); return Future.value(false); } try { // 确保Flutter绑定初始化,添加异常捕获 try { WidgetsFlutterBinding.ensureInitialized(); } catch (e) { 'Flutter binding failed: $e'.logs(); return Future.value(false); } // 延迟等待初始化完成 await Future.delayed(Duration(milliseconds: 100)); // 初始化存储依赖,添加异常处理 try { await AppStorage.init(); final appStorage = AppStorage(); Get.put(appStorage, permanent: true); } catch (storageError) { 'AppStorage initialization failed: $storageError'.logs(); return Future.value(false); } 'Executing background sync task: $task'.logs(); // 检查同步状态,异常时继续执行任务 try { final isSyncInProgress = await GlobalSyncStatus.isAnySyncInProgress(); if (isSyncInProgress == true) { 'Background sync skipped: some sync operations already in progress' .logs(); return Future.value(true); } } catch (syncCheckError) { 'Sync status check failed: $syncCheckError'.logs(); } // 执行同步任务,单个任务失败不阻断整体流程 try { await _performSyncWithErrorHandling(); 'Background sync task completed successfully.'.logs(); return Future.value(true); } catch (e) { 'Error during background sync: $e'.logs(); return Future.value(false); } } catch (e, stackTrace) { 'Background sync task failed: $e\n$stackTrace'.logs(); try { await GlobalSyncStatus.releaseAllSyncLocks(); } catch (_) {} return Future.value(false); } }); } // 单个同步任务独立异常处理 Future<void> _performSyncWithErrorHandling() async { final syncOperations = [ () => LocalDataSyncService.performAttendanceSync(), () => LeaveLocalDataSyncService.performLeaveSync(), () => CashAdvLocalDataSyncServices.performCashAdvSync(), () => SalaryAdvLocalDataSyncServices.performSalaryAdvSYnc(), () => VisitLocalDataSyncServices.performClientVisitSync(), ]; for (final operation in syncOperations) { try { await operation(); } catch (e) { 'Individual sync operation failed: $e'.logs(); } } }
2. 优化WorkManager初始化流程,清理旧任务
将WorkManager初始化独立拆分,更新APP时先清理所有旧任务,避免新旧任务冲突:
void main() async { try { await AppStorage.init(); Get.put(AppStorage(), permanent: true); await _initializeWorkManager(); runApp(DevicePreview( enabled: false, builder: (context) => MyApp( flavorConfig: FlavorConfig.development(), ), )); VersionHelper.getAppVersionAndSave(); } catch (e, stackTrace) { 'Error during app initialization: $e\n$stackTrace'.logs(); } } // 独立初始化WorkManager,添加完整异常处理 Future<void> _initializeWorkManager() async { try { // 更新后先清理所有旧任务 await Workmanager().cancelAll(); await Future.delayed(Duration(milliseconds: 1000)); // 初始化调度器 await Workmanager().initialize( callbackDispatcher, isInDebugMode: false, ); // 注册周期性任务,替换旧任务 await Workmanager().registerPeriodicTask( 'backgroundSyncTask', 'syncAttendanceAndLeave', frequency: const Duration(minutes: 15), constraints: Constraints( networkType: NetworkType.connected, ), existingWorkPolicy: ExistingWorkPolicy.replace, backoffPolicy: BackoffPolicy.exponential, ); 'WorkManager initialized successfully'.logs(); } catch (e, stackTrace) { 'WorkManager initialization failed: $e\n$stackTrace'.logs(); } }
关键修复点说明
- 旧任务清理:更新APP后取消所有旧任务,避免旧任务引用的代码路径与新版本不兼容导致NPE
- 空安全与异常捕获:在后台任务的各个关键节点添加空检查和异常捕获,防止单个环节失败导致整体崩溃
- 初始化顺序优化:确保Flutter绑定、依赖初始化完成后再执行同步任务,添加延迟等待初始化稳定性
- 任务容错设计:单个同步任务失败不阻断其他任务执行,提升后台任务的鲁棒性
内容的提问来源于stack exchange,提问作者Muneeza Muneer
相关产品推荐
相关产品推荐

