flutter 实现app进入后台之后持续活动

为了在 Flutter 应用进入后台后仍能保持活动状态,可以使用如下方法:

  1. 利用 Flutter 插件方式,通过 WidgetsBindingObserver 监听应用的生命周期变化。在应用进入后台之后,使用 Isolate.spawn() 启动一个新的分离的 Dart 代码执行器,从而保持应用继续运行。

具体实现步骤如下:

  1. 使用 WidgetsBindingObserver 监听生命周期变化:
class MyAppState extends State<MyApp> with WidgetsBindingObserver {
    
    
  // ...
  @override
  void initState() {
    
    
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
    void dispose() {
    
    
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    
    
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
    
    
      startIsolate();
    }
  }

  // ...
}

  1. startIsolate() 方法中启动新的 Dart 代码执行器:
void startIsolate() {
    
    
  IsolateNameServer.registerPortWithName(
      _backgroundChannelName, SendPort.receivePort);
  if (_isolate == null) {
    
    
    Isolate.spawn(backgroundTask, SendPort.receivePort);
  }
}

void backgroundTask(SendPort sendPort) async {
    
    
  final timer = Timer.periodic(Duration(seconds: 1), (Timer t) {
    
    
    print('background task running');
  });

  sendPort?.send(null); // dummy message
}

在上面的代码中,startIsolate() 方法启动了一个新的分离的 Dart 代码执行器,并在这个执行器中运行名为 backgroundTask() 的任务。该任务在 backgroundTask() 中简单地使用 Timer 定时输出一条日志信息。

需要注意的是,上面的代码所启动的分离代码执行器,与应用主线程之间没有共享数据的方式,但使用 IsolateNameServer 可以建立一个通道进行信息传输。即在 MyAppStateinitState() 方法中,可以添加下面这段代码来互相连接:

@override
void initState() {
    
    
  super.initState();
  WidgetsBinding.instance.addObserver(this);
  IsolateNameServer.registerPortWithName(ui.window.onReportTimings,
          'com.example.isolatesample.performance')
      .then((_) => print('Registered port'));
  IsolateNameServer.registerPortWithName(_backgroundChannelName,
          IsolateNameServer.lookupPortByName(_backgroundChannelName))
      .then((_) => print('Registered $_backgroundChannelName'));
}

  1. 使用 android_alarm_manager 插件并结合 flutter_isolate 插件实现应用进入后台仍可保持活动状态。

android_alarm_manager 插件可以用于在 Android 平台上通过 AlarmManager 启动后台 Dart 切片的计划。而 flutter_isolate 插件可以协助管理与创建切片和在切片之间传递消息。

具体实现步骤如下:

  1. pubspec.yaml 中添加 android_alarm_managerflutter_isolate 依赖:
dependencies:
  flutter:
    sdk: flutter
  android_alarm_manager: ^0.5.4+3
  flutter_isolate: ^1.0.1

  1. 添加 Android 工程设置。

  2. 创建一个新的切片 Dart 代码文件,在该文件中编写具体任务逻辑。

class ExecutionMessage {
    
    
  final int id;
  ExecutionMessage(this.id);
}

void main() async {
    
    
  final FlutterIsolate isolate = FlutterIsolate(getTask, name: 'BackgroundIsolate');
}

Future<void> getTask() async {
    
    
  print('BackgroundIsolate: Starting task...');

  final SendPort mainSendPort = IsolateNameServer.lookupPortByName(_isolateName)!;

  final ExecutionMessage message = const ExecutionMessage(42);

  Timer.periodic(Duration(seconds: 1), (_) {
    
    
    mainSendPort.send(message);
    print('BackgroundIsolate: Sent message $message');
  });
}

在这个切片处理代码文件中,首先使用 FlutterIsolate 初始化一个新的切片,随后使用 IsolateNameServer 获取 sendPort 并发送消息,最后使用 Timer.periodic() 来模拟一段任务逻辑。

  1. MyAppState 类中创建一个新的 Dart 代码切片,并使用 android_alarm_manager 来设置一个定时器并启动任务。
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter_isolate/flutter_isolate.dart';

class MyAppState extends State<MyApp> with WidgetsBindingObserver {
    
    
  late final FlutterIsolate _isolate;
  static const String _isolateName = 'isolate';

  Future<void> _initializeAlarm() async {
    
    
    await AndroidAlarmManager.initialize();

    await AndroidAlarmManager.oneShot(Duration(seconds: 5), 0, executeTask,
        allowWhileIdle: true, wakeup: true);
  }

  Future<void> executeTask() async {
    
    
    final SendPort mainSendPort = IsolateNameServer.lookupPortByName(_isolateName)!;

    final ExecutionMessage message = const ExecutionMessage(42);

    Timer.periodic(Duration(seconds: 1), (_) {
    
    
      mainSendPort.send(message);
      print('BackgroundIsolate: Sent message $message');
    });
  }

  //...
}

在这里,首先确保 android_alarm_managerflutter_isolate 插件初始化,接着使用 AndroidAlarmManager.oneShot() 设置一个定时任务,并在 _executeTask() 方法中执行逻辑。

启动应用之后进入后台一段时间,应该可以在控制台中看到如下类似的日志信息:

I/flutter (22731): BackgroundIsolate: Sent message Instance of 'ExecutionMessage'

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

猜你喜欢

转载自blog.csdn.net/weixin_43440181/article/details/130602196