参考文档 :

在这里插入图片描述





一、Flutter 后台保活底层机制




1、Flutter 后台保活底层机制


Flutter 后台保活 的 两大平台 底层机制差异 :

  • Android 平台 : 可以长期持续后台运行 , 核心依靠 Foreground 前台服务 + WakeLock 唤醒锁 + 电池白名单 , 独立 Dart 隔离区 (Isolate) , 退后台 / 锁屏也不会冻结线程 , WebSocket/HTTP 持续收发网络包 ;
  • iOS 平台 : 无法无限后台常驻 ( 系统强制冻结 ) , 没有真正永久保活 ; 只能组合以下三种机制 :
    • Audio 静音音频后台模式 ( 短期持续运行 , 易审核风险 )
    • Background Fetch + BGTaskScheduler 定时唤醒 ( 合规通用 )
    • 退后台十几秒后主线程直接挂起 , 只能靠 定时唤醒做心跳 / 重连 ;

2、flutter_background_service 插件简介


flutter_background_service 插件 是 Flutter 生态 跨平台后台常驻服务插件 , 核心能力 : 应用退后台、甚至完全划掉关闭后 , 依然独立运行 Dart 代码 , 不依赖前台页面 Isolate ;

  • Pub 地址 : https://pub.dev/packages/flutter_background_service
  • 支持 : Android + iOS、空安全、Dart3、Flutter 3.0+ , 最新稳定版 5.x
  • 授权 : MIT 开源

flutter_background_service 插件 底层封装原生系统后台能力 , 单独创建独立 Dart Isolate 执行后台逻辑 , 与 UI 主线程隔离 , 通过自定义消息通道实现「前台页面 ↔ 后台服务」双向通信 :

  • Android : 封装 Foreground Service ( 前台服务 ) , 常驻通知栏保活 ;
  • iOS : 封装系统 BGTaskScheduler + Background Fetch , 无真正无限后台 , 仅短周期定时任务Pub ;

3、Dart Isolate 简介


Isolate 直译 " 隔离区 " , 是 Dart 提供的并发执行单元 :

  • 每个 Isolate 独立内存、独立 GC、独立事件循环 ;
  • 隔离含义 : 一个 Isolate 崩溃不会干掉其他 Isolate ;
  • Isolate 之间唯一通信方式 : Port 消息传递 ( 复制传递数据 , 不共享引用 ) ;
  • Flutter App 默认自带 1 个 Main Isolate ( UI、渲染、业务逻辑都在这里 ) ;

Dart 是单线程语言 , 所有默认代码跑在 Main Isolate ( 主线程 ) , 只有一条事件循环 ( Event Loop ) , 不存在传统多线程共享内存 , Main Isolate ( Flutter UI 主线程 ) 特殊限制 :

  • 渲染、Build、Widget、Context 只能在 Main Isolate 使用 ;
  • 子 Isolate 不能调用 Flutter 渲染相关 API , 不能更新 UI ;
  • 如果子 Isolate 需要更新页面 : 只能通过 SendPort 发数据给主线程 , 主线 setState 更新界面 ;
  • 插件 MethodChannel、原生通道默认绑定主线程 , 子 Isolate 直接调用会报错 ;

Dart Isolate 与 操作系统 Thread 的 关键区别 :

  • 操作系统 Thread : 多线程共享堆内存 , 靠锁同步 ;
  • Dart Isolate : 内存完全隔离 , 每个 Isolate 拥有独立堆、独立 GC、独立事件循环 , 互相不能直接访问变量 ;
特性 Dart Isolate 操作系统 Thread
内存模型 完全独立堆 , 不共享 共享进程堆内存
同步机制 仅 Port 消息传递 锁、信号量、共享变量
崩溃影响 单个隔离区崩溃互不影响 一个线程崩溃整个进程退出
GC 每个 Isolate 独立 GC 进程全局 GC
Flutter UI 仅 Main Isolate 可操作 UI 任意线程都不能操作 UI


4、Isolate 核心组件 / 通信方式 / 独立内存


Isolate 核心组件 是 Event Loop ( 事件循环 ) : 每个 Isolate 独有一套事件循环 , 分两个队列 :

  • Microtask Queue ( 微任务 ) : 优先级更高 , 先执行完所有微任务再处理事件队列 ;
  • Event Queue ( 事件队列 ) : Future、Timer、IO、手势、网络、消息端口都放这里 ;

主线程卡顿本质 : 耗时同步代码阻塞 Event Loop , UI 渲染无法执行 → 界面卡死 ;

Isolate 就是用来 把耗时计算丢到另一个隔离循环 , 不阻塞 UI ;


Isolate 通信方式 : Isolate 无法直接访问对方变量 , 依靠 SendPort / ReceivePort 端口传消息 :

  • ReceivePort : 当前 Isolate 接收消息的端口 ;
  • SendPort : 发送消息到另一个 Isolate 的句柄 ;
  • 数据传递规则 :
    • 基础类型 ( int、String、bool、List、Map ) : 深拷贝复制 ;
    • 无法传递 : 函数、Widget、BuildContext、全局状态、文件句柄、网络连接 ;
  • 特殊 : SendPort 可以跨 Isolate 传递 , 作为通信桥梁 ;

每个 Isolate 隔离区 都有 自己 独立堆内存 和 CG 垃圾回收器 :

  • A Isolate 创建的对象 , B Isolate 完全不可见 ;
  • 各自都有一套 GC , 互不干扰 ;
  • 内存开销 : 每个新建 Isolate 会占用额外内存 , 不宜无限制创建 ;




二、使用 flutter_background_service 插件开发 Flutter 后台保活功能




1、添加插件依赖


在 pubspec.yaml 配置文件中 , 添加 flutter_background_service 依赖 ;

dependencies:
  flutter_background_service: ^5.0.5

配置完毕后 , 执行

flutter pub get

命令 , 安装插件 ;


2、添加 Android 权限 和 配置保活服务


android/app/src/main/AndroidManifest.xml 中 配置 以下权限 和 BackgroundService 保活服务 :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!-- 前台服务权限 -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
    <!-- 前台服务通知权限 -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

    <application
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <!-- 后台保活服务 -->
        <service
            android:name="id.flutter.flutter_background_service.BackgroundService"
            android:foregroundServiceType="location"
            android:exported="false"
            android:stopWithTask="false"
            android:enabled="true"
            tools:replace="android:exported" />
    </application>
</manifest>

3、android/app/build.gradle 配置


android/app/build.gradle 配置 最低 API 版本 : 注意 最低版本 要求 21 版本 ;

defaultConfig {
    minSdkVersion 21
    targetSdkVersion 34
}

4、iOS 后台配置


调用 open ios/Runner.xcworkspace 命令 , 使用 Xcode 打开 Flutter 的 iOS 项目 ;

  • 选中 Runner Target → Signing & Capabilities ;
  • 点击 + Capability , 搜索添加 Background Modes ;
  • 勾选两项核心模式 :
    • Background fetch ( 周期唤醒 )
    • Background processing ( 支持稍长数据处理 )
  • 额外场景补充 :
    • 后台 GPS 轨迹 : 追加勾选 Location updates
    • 后台音乐播放 : 追加勾选 Audio, AirPlay
      在这里插入图片描述

5、iOS 的 Info.plist 配置


在 iOs/Runner/Info.plist 中 配置如下 键值对 :

<key>UIBackgroundModes</key>
<array>
  <string>fetch</string>
  <string>processing</string>
</array>
<!-- 后台刷新描述 , 审核必填 -->
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
  <string>com.xxx.app.syncservice</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

6、Flutter 代码参考


Flutter 代码参考 :

import 'dart:async';
import 'dart:ui';

import 'package:flutter_background_service/flutter_background_service.dart';

/// 后台独立进程启动顶层回调方法
/// 强制要求顶层独立函数 , 不能封装在类内部
/// @pragma('vm:entry-point') 注解用于AOT编译 , 让Native引擎能够找到该后台入口
/// 该方法运行在全新独立Dart隔离区 , 与前端UI线程内存完全隔离
('vm:entry-point')
void isolateTaskBootEntry(ServiceInstance service) {
  // 后台隔离区初始化注册Flutter底层引擎
  // 增加try-catch捕获插件底层潜在初始化异常 , 避免后台进程直接崩溃退出
  try {
    DartPluginRegistrant.ensureInitialized();
  } catch (e) {
    print('多进程管理工具 后台隔离引擎初始化捕获可忽略异常 : $e');
  }

  print('多进程管理工具 后台独立进程已触发启动回调');

  // 监听前端发送的进程停止指令 , 收到后主动销毁后台服务
  service.on('stop').listen((event) {
    service.stopSelf();
    print('多进程管理工具 收到前端停止指令 , 后台独立进程已销毁');
  });

  // 后台常驻循环定时器 , 每5秒打印运行日志 , 用于验证进程存活状态
  Timer.periodic(const Duration(seconds: 5), (timer) {
    print('多进程管理工具 后台独立进程持续正常运行中...');
  });

  print('多进程管理工具 后台进程启动回调执行完毕 , 常驻任务已开启');
}

/// iOS系统定时唤醒后台任务顶层方法
/// iOS系统无法永久常驻后台 , 依靠系统定时调度触发该方法执行轻量任务
/// 必须顶层函数并添加vm入口注解 , 否则系统调度时无法执行
('vm:entry-point')
Future<bool> isolateIosBackgroundTimerTask(ServiceInstance service) async {
  // iOS后台唤醒后 , 必须重新初始化Flutter引擎注册器
  DartPluginRegistrant.ensureInitialized();

  // iOS后台唤醒后启动定时日志循环 , 校验唤醒后进程可正常执行代码
  Timer.periodic(const Duration(seconds: 5), (timer) {
    print('iOS定时后台任务 唤醒后任务持续执行中...');
  });

  print('多进程管理工具 iOS系统定时唤醒任务已执行');
  return true;
}

/// 跨平台后台进程统一管理工具类
/// 底层依赖 flutter_background_service 插件实现App后台保活能力
/// 同时兼容Android、iOS两大移动端系统 , 两套系统差异化配置统一封装
/// 采用饿汉单例设计模式 , 全局仅存在唯一管理实例 , 避免多实例冲突
class AppBackgroundTaskManager {
  /// 饿汉单例核心静态常量
  /// 程序加载阶段直接创建唯一实例 , 全局任意位置调用均使用同一个对象
  static final AppBackgroundTaskManager instance =
      AppBackgroundTaskManager._privateConstructor();

  /// 私有内部构造方法
  /// 私有化后外部无法通过 new/构造函数手动创建新实例 , 保证单例唯一性
  AppBackgroundTaskManager._privateConstructor() {
    print('多进程管理工具 全局单例对象完成初始化创建');
  }

  /// 对外暴露工厂构造函数
  /// 外部代码直接调用类名()即可获取全局唯一实例 , 使用方式更简洁
  factory AppBackgroundTaskManager() => instance;

  /// flutter后台服务底层原生实例对象
  final FlutterBackgroundService _backgroundServiceCore = FlutterBackgroundService();

  /// 标记后台进程当前运行状态
  bool _serviceRunningFlag = false;

  /// 只读对外状态获取器
  /// 外部仅能读取运行标记 , 无法直接修改内部状态变量
  bool get isServiceRunning => _serviceRunningFlag;

  /// 后台进程全局初始化配置方法
  /// 统一配置Android前台服务参数、iOS后台调度参数
  /// 程序启动阶段仅执行一次 , 不可重复调用configure方法
  Future<void> initGlobalBackgroundConfig() async {
    await _backgroundServiceCore.configure(
      androidConfiguration: AndroidConfiguration(
        // Android进程启动绑定顶层隔离任务入口方法
        onStart: isolateTaskBootEntry,
        // App启动自动拉起后台服务
        autoStart: true,
        // 开启前台服务模式 , Android保活核心开关 , 状态栏常驻通知防止系统休眠冻结进程
        isForegroundMode: true,
        // 使用插件内置默认通知渠道 , 无需开发者手动在原生层创建渠道资源
        // 若自定义渠道ID , 必须同步在Android原生代码创建对应通知渠道 , 否则前台通知不展示
        // 前台服务通知唯一标识ID , 避免与App其他通知冲突
        foregroundServiceNotificationId: 888,
        // 状态栏前台通知标题文本
        initialNotificationTitle: '应用后台同步服务',
        // 状态栏前台通知详情描述 , 告知用户后台服务作用
        initialNotificationContent: '应用后台同步服务正在持续运行 , 保障数据实时同步',
      ),
      iosConfiguration: IosConfiguration(
        // App未完全退出、退至后台短时运行时执行的隔离任务
        onForeground: isolateTaskBootEntry,
        // iOS系统定时周期唤醒执行的轻量化后台任务
        onBackground: isolateIosBackgroundTimerTask,
        // App启动自动初始化后台调度配置
        autoStart: true,
      ),
    );

    print('多进程管理工具 跨平台后台进程全局配置已完成');
  }

  /// 启动后台独立保活进程主方法
  /// 调用底层插件接口拉起隔离后台进程 , 更新内部运行状态标记
  Future<void> launchBackgroundTask() async {
    // 已删除电池优化、厂商自启动引导相关全部逻辑 , 无额外前置系统设置操作

    final bool launchResult = await _backgroundServiceCore.startService();
    _serviceRunningFlag = launchResult;
    if (launchResult) {
      print('多进程管理工具 后台独立保活进程启动成功');
    } else {
      print('多进程管理工具 后台独立保活进程启动执行失败');
    }
  }

  /// 主动停止后台保活进程方法
  /// 向前台隔离进程发送停止指令 , 修改运行状态标记
  Future<void> shutdownBackgroundTask() async {
    _backgroundServiceCore.invoke('stop');
    _serviceRunningFlag = false;
    print('多进程管理工具 后台独立保活进程停止指令已下发');
  }
}

7、Flutter 初始化后台服务


初始化后台服务入口 :

  // 第一步 : 全局初始化跨平台后台保活独立进程配置
  await BgTaskGlobalManager().setupCrossPlatformBgConfig();

  // 第二步 :  执行启动后台常驻保活进程
  await BgTaskGlobalManager().startGlobalBgTask();
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐