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

Flutter使用workmanager包时引擎停止运行闪退 疑似与flutter_tesseract_ocr冲突

问题现象

该问题仅在使用 workmanager 包时触发,触发注册的后台任务后应用直接崩溃,初步怀疑是workmanager与部分Google相关依赖包或 flutter_tesseract_ocr 包存在兼容性冲突。

业务实现代码

void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) {
    print('I dont know what happens so help');
    return Future.value(true);
  });
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebasePushHandler);
  MobileAds.instance.initialize();
  await CacheHelper.init();
  await EasyLocalization.ensureInitialized();
  await CacheHelper.removeData('isshown');
  DioHelper.init();
//Work manager initializtion
  Workmanager().initialize(
    callbackDispatcher, // 顶层回调调度函数
  );
  index = CacheHelper.getData(key: 'index') ?? 0;
  String? uid = CacheHelper.getData(key: 'uid');
  await NotificationApi.init();
  BlocOverrides.runZoned(
    () {
      runApp(
        EasyLocalization(
            supportedLocales: const [Locale('en'), Locale('ar')],
            path: 'assets/lang', // 翻译文件存放路径
            assetLoader: const CodegenLoader(),
            fallbackLocale: const Locale('en'),
            child: MyApp(uid)),
      );
    },
    blocObserver: MyBlocObserver(),
  );
}

/// 后台任务注册逻辑
Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        HapticFeedback.lightImpact();
        setState(() {
          controller!.forward();
        });
        // Workmanager().cancelAll();
        Workmanager().registerOneOffTask('awsomeNotification', 'notify',
            initialDelay: const Duration(seconds: 5));
      },
      child: CardStack(controller!, widget.slideNum, widget.slideText),
    );
  }

崩溃运行日志

W/MediaSessionCompat(12770): Couldn't find a unique registered media button receiver in the given context.
W/FlutterJNI(12770): FlutterJNI.loadLibrary called more than once
I/ResourceExtractor(12770): Found extracted resources res_timestamp-1-1656733798661
W/FlutterJNI(12770): FlutterJNI.prefetchDefaultFontManager called more than once
W/FlutterJNI(12770): FlutterJNI.init called more than once
D/AndroidRuntime(12770): Shutting down VM
E/AndroidRuntime(12770): FATAL EXCEPTION: main
E/AndroidRuntime(12770): Process: com.areading.amaa, PID: 12770
E/AndroidRuntime(12770): java.lang.NullPointerException: Attempt to invoke virtual method 'void com.googlecode.tesseract.android.TessBaseAPI.recycle()' on a null object reference
E/AndroidRuntime(12770):    at io.paratoner.flutter_tesseract_ocr.FlutterTesseractOcrPlugin.onDetachedFromEngine(FlutterTesseractOcrPlugin.java:42)
E/AndroidRuntime(12770):    at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.remove(FlutterEngineConnectionRegistry.java:270)
E/AndroidRuntime(12770):    at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.remove(FlutterEngineConnectionRegistry.java:280)
E/AndroidRuntime(12770):    at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.removeAll(FlutterEngineConnectionRegistry.java:288)
E/AndroidRuntime(12770):    at io.flutter.embedding.engine.FlutterEngineConnectionRegistry.destroy(FlutterEngineConnectionRegistry.java:121)
E/AndroidRuntime(12770):    at io.flutter.embedding.engine.FlutterEngine.destroy(FlutterEngine.java:425)
E/AndroidRuntime(12770):    at be.tramckrijte.workmanager.BackgroundWorker.stopEngine$lambda-2(BackgroundWorker.kt:137)
E/AndroidRuntime(12770):    at be.tramckrijte.workmanager.BackgroundWorker.lambda$u5fs2CPxJ29Hdjbap5WYUt2tGrg(Unknown Source:0)
E/AndroidRuntime(12770):    at be.tramckrijte.workmanager.-$$Lambda$BackgroundWorker$u5fs2CPxJ29Hdjbap5WYUt2tGrg.run(Unknown Source:2)
E/AndroidRuntime(12770):    at android.os.Handler.handleCallback(Handler.java:938)
E/AndroidRuntime(12770):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(12770):    at android.os.Looper.loopOnce(Looper.java:210)
E/AndroidRuntime(12770):    at android.os.Looper.loop(Looper.java:299)
E/AndroidRuntime(12770):    at android.app.ActivityThread.main(ActivityThread.java:8168)
E/AndroidRuntime(12770):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(12770):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
E/AndroidRuntime(12770):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037)
I/WM-WorkerWrapper(12770): Worker result SUCCESS for Work [ id=58f0ee16-1de5-42d8-ae78-1d789ea5125f, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
D/OOMEventManagerFK(12770): checkEventAndDumpForJE: 0
I/Process (12770): Sending signal. PID: 12770 SIG: 9
Lost connection to device.
Exited (sigterm)
根因定位

从崩溃栈可以明确问题触发链路:

  1. workmanager执行完后台任务后,会销毁后台执行使用的独立FlutterEngine实例
  2. 引擎销毁过程中会回调所有已注册插件的onDetachedFromEngine生命周期方法
  3. flutter_tesseract_ocr 插件的该回调方法没有做非空判断,直接对从未初始化过(后台任务未使用OCR能力,TessBaseAPI实例为null)的对象调用recycle()方法,触发空指针异常
  4. 异常未被捕获,直接导致应用进程被系统强制终止,设备连接断开。
修复方案
  • 临时本地修复:打开本地pub缓存中flutter_tesseract_ocr插件的android源码文件,路径为~/.pub-cache/hosted/pub.dev/flutter_tesseract_ocr-<对应版本号>/android/src/main/java/io/paratoner/flutter_tesseract_ocr/FlutterTesseractOcrPlugin.java,定位到onDetachedFromEngine方法,在调用recycle()前增加非空判断:
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    // 新增非空判断逻辑
    if (tessBaseAPI != null) {
        tessBaseAPI.recycle();
    }
    channel.setMethodCallHandler(null);
}
  • 长期方案:如果不需要在workmanager的后台任务中使用OCR能力,可以在workmanager的回调调度逻辑中屏蔽无关插件的自动注册;也可以将该问题提交给flutter_tesseract_ocr插件维护者,等待官方发布修复版本。

内容的提问来源于stack exchange,提问作者abdallah mostafa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:15:47