当iOS部分使用蓝牙中心后台执行模式时,如何暂停Flutter在后台运行

ycggw6v2  于 12个月前  发布在  iOS
关注(0)|答案(3)|浏览(198)

我的应用程序使用CoreBluetooth状态恢复和保存(SRP)连接到BLE附件,并使用bluetooth-central后台执行模式。这意味着即使应用程序处于后台,用Swift编写的应用程序的本机部分也可以连续接收HR样本。然而,我还可以看到的是,尽管应用程序处于paused生命周期状态,但应用程序的Flutter部分仍在运行。
我做了一个简单的实验,当使用不使用核心蓝牙SRP时,在Flutter中启动计时器。

  • 不使用SRP时,计时器在20秒后停止打印到日志中
  • 使用SRP时,只要BLE附件发送HR样本,计时器就会无限期运行

我所寻找的是保持 * 典型 * 的Flutter行为,但继续在本机端使用SRP。

  1. Flutter的哪个部分负责在应用程序进入暂停状态时停止“执行”?
    1.尽管SRP保持应用程序唤醒(由于使用bluetooth-central模式并接收连续的HR更新),但Flutter是否可以暂停?
    1.有没有一种方法可以通过编程将Flutter引擎置于paused状态?
    1.如果没有,你有没有看到任何其他的方法来保持 * 典型的 * Flutter引擎/ViewController行为?
whitzsjs

whitzsjs1#

这里的问题是某种误解。当Flutter部分是paused,时,并不意味着它默认暂停执行。当你进入这种状态时,你必须手动暂停所有需要的东西。
对于大多数“functional(non ui)”的情况,这些状态WidgetsBindingObserver捕获仅仅是“指示”而不是“动作”.
以下是official documentation的一些解释:

paused → const AppLifecleState

应用程序当前对用户不可见,并且不响应用户输入。
当应用程序处于此状态时,引擎将不会调用PlatformDispatcher.onBeginFrame和PlatformDispatcher.onDrawFrame回调。
此状态仅在iOS和Android上输入。>
这意味着Flutter引擎只会跳过屏幕上的绘制内容-所有其他操作都是活动的,并且会一直活动到应用程序死亡。在iOS中,直到明确杀死应用程序之前,它可能永远不会发生。在Android中,操作系统可以在任意时间杀死它或不杀死它-这取决于操作系统本身的负载。
要在paused状态下忽略任何活动,您必须显式地手动取消订阅paused状态下的任何侦听器,并在resumed状态下再次订阅它们。我说“订阅”和“取消订阅”这样的词是因为我不知道您的代码的细节-您可能很容易忽略所有事件或其他东西。
如果你想让flutter部分在应用程序处于后台时根本不起作用,你必须手动杀死flutter部分-如果你手动建立了flutter引擎连接,而不是依赖于FluttFlutterViewControllerFlutterFragment等,你就可以做到这一点。你必须控制代码才能做到这一点。之后,当你的应用程序再次处于前台时(要知道你必须依赖本机回调,因为当flutter引擎停止工作时,dart代码中没有回调),你将能够重新建立flutter基础设施并再次运行它。
我不推荐后一种方法,因为它太多余了--在大多数情况下,忽略事件和/或订阅/取消订阅就足够了。
希望对你有帮助。

yruzcnhs

yruzcnhs2#

Flutter在后台的行为,特别是与原生模块集成时,有时会导致非标准行为。以下是对您具体问题的回答和建议,以帮助您:

1.当应用进入暂停状态时,Flutter的哪个部分负责停止“执行”?

Flutter的AppLifecycleState管理Flutter应用的不同生命周期状态。通常,当应用进入后台时,它会进入暂停状态,这应该会停止Flutter的大部分活动。这是在引擎级别管理的。

2.即使SRP打开,Flutter也可以暂停吗?

在CoreBluetooth中使用状态恢复和保存时,您的应用的原生部分即使在后台也会保持活动状态。但是,除非通过平台通道显式通信,否则Flutter应该不知道此后台活动。Flutter的引擎应该仍然像往常一样暂停,除非您的集成中有什么导致它保持活动状态。

3.有没有办法以编程方式将Flutter引擎置于暂停状态?

Flutter引擎会响应iOS生命周期事件(如UIApplicationDidEnterBackgroundNotification),但你不能从Dart强制Flutter引擎进入暂停状态。

4.如果没有,你有没有看到其他方法来保持典型的Flutter引擎/ViewController行为?

以下是一些建议:

**解释性Activity:**在您的应用进入后台之前,您可以使用Flutter的WidgetsBindingObserver来侦听生命周期事件,并暂停您在Flutter中启动的任何计时器或Activity。

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) {
    if (state == AppLifecycleState.paused) {
      // Pause your timers or other activities here
    }
  }
}

字符串

**平台通道:**使用平台通道在应用的原生端和Flutter端之间进行通信。如果原生端意识到它将进入不应激活Flutter的后台模式,请向Dart端发送消息以暂停任何Activity。
**检查集成:**确保您集成的CoreBluetooth或任何其他本机模块不会无意中使Flutter引擎保持唤醒状态。例如,如果您通过平台通道持续从本机端向Flutter发送数据,则可能会使Flutter引擎保持活动状态。
**重新考虑架构:**如果可能的话,考虑重新构建,使Flutter不需要知道后台BLE活动。在原生端收集数据,并在应用进入前台时与Flutter同步。

虽然您无法直接强制Flutter引擎进入暂停状态,但您可以基于生命周期状态管理应用的Activity,并确保后台Activity不会无意中使Flutter保持唤醒状态。

wj8zmpe1

wj8zmpe13#

如果可能的话尝试小部件

我不确定你的确切环境,但部件可以对应用程序状态做出React。

import 'package:flutter/widgets.dart';

class MyAppLifecycleObserver extends WidgetsBindingObserver {
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) {
      // Perform necessary operations or stop/pause execution.
    } else if (state == AppLifecycleState.resumed) {
      // Resume execution or resume any paused operations.
    }
  }
}

字符串

相关问题