如何获取Flutter FFI调用的C语言函数的执行完成百分比?
Flutter FFI调用C语言耗时函数进度上报可行方案
方案1:共享内存轮询
- C侧定义
atomic_int类型的全局原子变量存储进度值(范围0-100),保证多线程读写安全 - 耗时C函数执行的各阶段同步更新该原子变量的数值
- Flutter侧开启固定间隔的轮询任务(可使用
Timer.periodic或独立Isolate),每间隔100~200ms通过FFI调用C侧暴露的int get_progress()接口读取当前进度,同步更新UI进度条 - C函数执行完成后销毁轮询任务,重置进度变量
优点:实现逻辑简单,C侧无需感知Dart层逻辑,性能开销极低,适合高要求性能场景
缺点:进度更新存在固定延迟,延迟时长取决于轮询间隔,无法实现实时触发
方案2:FFI异步回调(最常用)
- Dart层先定义进度回调函数签名:
typedef ProgressCallback = void Function(int progress);,将写好的进度更新逻辑通过Pointer.fromFunction转为C侧可识别的函数指针,调用C函数时作为参数传入 - C侧保存传入的函数指针,耗时函数执行到对应进度节点时,直接调用该函数指针上报当前进度
- 若C函数运行在独立POSIX线程中,禁止直接调用Dart侧传入的函数指针,需使用FFI原生API
Dart_PostCObject将进度事件发送到Dart主Isolate,避免线程冲突崩溃 - Dart层收到回调的进度值后直接更新UI即可
优点:进度更新实时无延迟,无需轮询额外开销,逻辑清晰可跨平台复用
缺点:需要处理跨线程调用安全问题,实现复杂度略高于轮询方案
方案3:安卓平台专属EventChannel中转
- C侧通过JNI接口将进度值回调给安卓原生Java/Kotlin层
- 原生层收到进度后,通过Flutter
EventChannel将进度事件流发送到Dart层 - Dart层监听事件流,收到进度值后更新UI
优点:无需处理FFI跨线程回调的复杂逻辑,熟悉安卓原生开发的场景下上手快
缺点:仅适配安卓平台,无法复用至iOS/桌面端,多一层中转性能稍差
注意事项
- C侧所有进度读写操作必须做线程安全处理,避免多线程并发读写出现脏数据
- 若C函数执行阶段非常细碎,可设置上报阈值(例如进度变化≥1%才上报),避免回调过于频繁导致UI卡顿
- 耗时C函数必须运行在独立线程/Isolate中,禁止阻塞Dart主进程,否则进度UI会出现卡顿无响应的问题
内容的提问来源于stack exchange,提问作者AJITH PINNINTI
相关产品推荐
相关产品推荐

