You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 14:14:55