Flutter: Flutter 应该为后台执行提供一个抽象

创建于 2016-05-02  ·  139评论  ·  资料来源: flutter/flutter

客户希望在 iOS 和 Android 上将 dart 代码作为后台进程执行,例如在 wifi 可用但应用程序未打开时同步数据等。

@mpcomplete在 Android 上创建了一个后台进程来执行 Dart 代码来更新 Flutter。 但我不知道 iOS 上有类似的情况。

此问题跟踪插件或其他方式中 API 的开发。 在https://github.com/flutter/flutter/issues/6192 中跟踪了对这些抽象的引擎支持。

truckable wellbeing engine framework plugin new feature

最有用的评论

快速更新:iOS 的后台执行已实现并等待审核 (PR flutter/engine#5539)。 一旦登陆,我将开始更新 Android 后台执行以具有一致的界面并发布示例插件。 这一切都有望在月底前完成。

所有139条评论

后台运行的代码应该用 Dart 还是 Java/Objective-C 编写?

这是在连接可用时想要更新本地数据模型的背景下出现的。 例如地铁地图/您可能进出地铁的时间。 所以我认为目标是让执行的代码成为 Dart,这样你就不必为每个平台都有单独的数据模型操作代码。

抄送@kasperl; 我们已经探索了许多在不同目标的后台执行代码的方法,也许可以从中吸取一些教训。

我们有来自用户的一些用例吗? 我唯一听到的是“我们想在设备上运行一些代码,以响应推送消息。我们想将数据同步到设备上,即使应用程序没有打开。”

它通常非常限制应用程序在后台实际允许执行的操作,因此在这种情况下,我认为我们可以从那里获得用例的灵感。 例如,这里是 iOS 模型:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

我相信这与 #6192 是相同的错误,是的。

从 #6192 添加多叶标签和里程碑值

@mravn-google @sigurdm值得考虑的事情!

分配给 Mikkel 进行初步调查,以更好地了解可行性和成本。

以下是来自 Leafy 的更新:

由于数据通知的限制(即需要应用程序以某种方式响应的通知),leafy 倾向于使用显示通知(即直接推送到用户屏幕而无需应用程序参与的通知)。 Flutter 中已经存在对这些的支持。

然而,在与其他团队的对话中,另一个用例浮出水面:如果你想从你的应用程序中支持可穿戴设备或 [主屏幕] 小部件,你需要用本机代码编写 UI,因为 Flutter 尚不支持这些表面。 但是,如果能够“唤醒应用程序并请求数据”,这样模型层和业务逻辑就可以在 Flutter 应用程序和可穿戴应用程序之间共享,那就太好了。 由于从未编写过其中之一,我不确定现有的原生应用程序是如何做到这一点的,但它确实似乎是后台任务的有效用例。

刚刚与柏林 DroidCon 的 Flutter 演讲的作者进行了交谈,这是他最关心的问题之一。 “如何做到这一点,Flutter 方式”

需要明确的是,目前可以将后台进程编写为使用 Flutter 的应用程序的一部分。 然而,这些进程只能执行 Obj-C/Swift 或 Java/Kotlin 代码。 这个错误是关于修复我们引擎中的限制以允许在这些后台进程中执行 Dart 代码,以及可能提供一个抽象来允许从 Dart 调度此类后台工作(一旦 FlutterView-needs-to- 可能属于插件屏幕上的限制被删除)。

https://github.com/flutter/flutter/issues/6192#issuecomment -258928555 讨论了当前的引擎限制以及我们解决它的意图。 仅供参考@a-siva

我们有一个我没有提到的用例:我们每 5 秒进行一次位置跟踪,并且将某些其他信息附加到该事件,所有这些业务逻辑都在 Dart 中实现。 如果我们的用户将另一个活动带到前台,我们需要显示一个持久通知并继续每 5 秒运行一次该 Dart 代码。

这对我们来说是一个障碍。 我很想听听我们目前可以实施的任何解决方法,因为这会延迟发货。

我会尝试简单地让计时器保持活动状态,看看会发生什么。 我认为它不可靠,但我们的应用程序也有一次性缓存清理的用例(应用程序进入后台后 15 分钟),我们已经看到它成功执行。 我们在应用程序在 Dart 中停止时安排它。 像这样的东西:

<strong i="6">@override</strong>
void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused) {
        new Future.delayed(const Duration(seconds: 5), () => _doSomething());
    }
}

如果出现以下情况,它将不起作用:

  • 应用程序被用户明确杀死(例如从任务切换器中)。
  • 由于内存压力,应用程序被操作系统杀死。
  • 在 iOS 上? 我认为我们没有尝试过,所以请随时尝试并报告。

我不确定 iOS 对应的版本,但在 Android 上,可以创建一个启动前台服务的颤振插件,从而为进程提供更高的优先级,并使其在资源需求时不太可能被杀死。 这是否也会给长期运行的 Dart 计时器带来更好的生存机会?

是的,这可能会有所帮助,因为您的活动(因此您的颤动视图)将保持活动状态。 我仍然不相信我们有足够的清晰度来做一个插件。

如果重点是支持定期后台轮询信息,那么为此设计一个插件可能会更好。 它应该允许在 Dart 中注册一个回调,该回调是通过本机代码中的计时器调用的,而不是在 Dart 中实现计时器。 我们可以通过 Android 上的服务来做到这一点。

或者

我们可以简单地拥有一个 HowTo 来创建 KeepAlive™ Flutter 应用程序。

在 iOS 上,您可以在Info.plist中设置UIBackgroundMode以降低应用程序被杀死的可能性。

在 Android 上,设置一个空服务。 这主要是 AndroidManifest.xml 更改 + 一个微不足道的服务类实现。

一个通用的 KeepAlive 插件似乎不可行,因为它仍然需要在 iOS 上手动设置,并且不清楚是否在 Android 上使用前台/后台服务(前台服务更难杀死,但需要持续通知)。

即使有前台服务,操作系统仍然可以出于任何原因终止我们的进程。

我认为理想的解决方案必须使用 Android 的警报管理器,它适用于您希望在特定时间运行应用程序代码的情况,即使您的应用程序当前没有运行。 但即便如此,我们如何重新启动具有相同状态的 Dart 进程,因为我们将有一个登录的 Firebase 用户进行经过身份验证的数据库写入?

@pauldemarco因此这个错误...... Flutter 现在无法在任何状态下执行 Dart 代码,而 FlutterView 正在运行。 这包括警报管理器、可穿戴/原生小部件数据同步或推送通知(尽管最后一个的用例正在慢慢消失 https://github.com/flutter/flutter/issues/6192)。

我认为 _same state_ 问题应该在应用程序级别而不是在 Flutter 级别解决。 对于本机应用程序,您也有同样的问题。 一旦进程死亡,除非将其保存在某个地方(例如共享首选项或 sqlite),否则您将无法恢复状态。 大概你会在你的 Dart 代码中做同样的事情。 Flutter 可以做的一件事是传达诸如 iOS 上的applicationWillTerminate和 Android 上的onSaveInstanceState之类的消息,这样您就可以为此做好准备。

问题:

  • 后台执行的 iOS 和 Android 模型是什么?

    • 哪些信号可以触发应用程序运行?

    • 你需要跑多长时间? 你怎么知道什么时候用完?

  • 我们想要什么样的执行模型用于后台执行? (例如单独的隔离?使用主 dart:ui 线程?)
  • 我们是否希望支持在没有应用程序(如runApp )首次运行的情况下运行代码?
  • 我们可以收集一个规范的用例列表吗?

目前,这还没有计划在不久的将来。 这是一个很大的过程,我们需要尽快从我们的短期优先事项列表中删除一些其他内容。

用例
我们有不同的操作模式,以不同的时间间隔(5 秒、10 分钟、30 分钟、6 小时)记录事件。 我们需要一种方法来确保无论应用程序当前是否正在运行,日志记录过程都会运行。

哪些信号可以触发应用程序运行?

在 Android 上,这将通过从 AlarmManager 中的预定警报发送的 PendingIntent。
目前我不确定 iOS 是否与此对应。

你需要跑多长时间? 你怎么知道什么时候用完?

我们必须首先收集事件所需的信息,其中一些是异步的(GPS 位置),然后将事件记录在在线数据存储区(Firebase)中。 整个过程可持续长达 30 秒。

我们想要什么样的执行模型用于后台执行? (例如单独的隔离?使用主 dart:ui 线程?)

我认为这对我们来说并不重要,我们不会进行任何昂贵的计算。

我们是否希望支持在没有应用程序(如 runApp 中)首次运行的情况下运行代码?

我不确定这里的含义。 我想既然我们在普通应用程序中初始化了我们的业务逻辑和状态,最好先运行这些东西,这样我们就可以利用崩溃报告等。

我可以添加另一个用户案例,这个功能是唯一让我无法完成我的应用程序的事情。 我为此有一个 android 应用程序,并决定创建一个更新、更好的版本,理想情况下也可以在 iOS 上运行。 我不熟悉 iOS 中的组件(研究时我发现 iOS 中的后台任务比 android 上的限制要多得多)但我可以命名我使用的 Android 组件。

哪些信号可以触发应用程序运行?

大多数代码也是由 AlarmManager 中的警报触发的。

但是,要在设备启动和包升级(android.intent.action.MY_PACKAGE_REPLACED)时执行一些代码时始终启动该警报,因为之前的警报将被删除。

你需要跑多长时间? 你怎么知道什么时候用完?

理想情况下不到一秒钟。 发出一个小的网络请求并保留结果,在某些情况下会显示通知。 之后该方法返回。

我们想要什么样的执行模型用于后台执行? (例如单独的隔离?使用主 dart:ui 线程?)

对我也无所谓。

我们是否希望支持在没有应用程序(如 runApp 中)首次运行的情况下运行代码?

在我的情况下,运行一次就可以了,但是如果可以使用启动接收器之类的东西,即使应用程序之前没有启动它也应该运行。

https://stackoverflow.com/questions/41924890/how-do-i-run-code-in-the-background-even-with-the-screen-off 是 Fl​​utter 最受关注的堆栈溢出问题告诉。 :) 似乎对这个空间很感兴趣。

https://github.com/flutter/flutter/issues/6192已重新激活,以便在 FlutterView 未呈现时为实际运行 Dart 代码提供底层支持。

这是我们近期的雷达,但至少需要几个月。

抱歉从这个错误中取消分配@zanderso ,我的意思是把他分配给底层的后台执行错误(#6192)

抄送@kasperl; 我们已经探索了许多在不同目标的后台执行代码的方法,也许可以从中吸取一些教训。

@mit-mit 您是否以某种形式或形式记录了您的发现?

需要后台处理的另一个原因是如果您想创建一个流式音频应用程序。 用户打开应用程序以启动音频流。 后台进程下载流并播放音频结束接收事件以开始/停止/暂停/ff/倒带结束发送事件以更改 UI,例如将搜索栏音频元数据发送到 UI。 当用户离开您的应用程序 ui 时,您需要一个后台进程,流的下载/播放需要继续

我们目前正在为此努力。 目前没有预计到达时间。

@zanderso在这里发布了更新: https ://github.com/flutter/flutter/issues/6192#issuecomment -342214725

@a-siva 告诉我这仍在进行中; Android 已启动并正在运行,我们现在正在开发 iOS。

我们有一个用例,我们希望在后台跟踪用户位置,以记录他们是否在特定时间(即在事件期间)去了特定位置。

@bjornbjorn你不能为此使用地理围栏吗? 不知道IOS有没有类似的东西但是你可以实现这个Play Service Geofencing

@Hixie有什么消息吗? 我目前处于需要我的应用程序作为后台服务运行的阶段(大部分应用程序都是用 Go 编写的),但它最终会被杀死。 我开始在 Java 端实现前台服务,但如果我最终必须为 iOS 重新实现它,那将会非常讨厌。

有人估计这是否会在下周或下个月适用于 android 将非常感激 :)

@rusenask详见https://github.com/flutter/flutter/issues/6192 ,我们现在在 Android 上有一个插件! 请查看https://pub.dartlang.org/packages/android_alarm_manager ,如果满足您的要求,请告诉我们。

它看起来很有希望,我可能会使用该警报管理器将我的应用程序从“守护程序”样式更改为更像“周期性爆发”。 要醒来,请阅读任何新闻并关机。

但是,理想情况下,我会使用一些允许我的进程始终在前台运行的东西。 https://stackoverflow.com/questions/15758980/android-service-needs-to-run-always-never-pause-or-stop 。 简而言之,我的应用程序运行一个机器人,所以它几乎总是需要运行。

在我们考虑完成之前,我们需要确保我们已经记录了这一点。

我们应该打开一个新的文档问题吗?

添加到https://github.com/flutter/website/pull/802中的常见问题解答

@zanderso -- @mjohnsullivan是文档方面的最佳联系人。

ETA 是否已知?

@it2bz ETA 到底是为了什么? 支持安卓吗? 文档? 在 iOS 上支持? 例子?

@Hixie在 Android 和 iOS 上的支持以及至少带有示例的基本文档

对于 iOS,你能详细说明你想要什么吗? Apple 对应用程序可以在后台执行的操作有严格的限制,因此我们最好知道您希望我们连接哪些 API。

我正在寻找与用户位置相关的机会背景工作

看起来这是“询问背景资料”线程,所以我将开始。 我想使用颤振实现一个音乐播放器,但我不确定即使应用程序在手机上被最小化,是否有可能(API 明智)保持音乐播放。 我知道在 Android 上,您可以启动一项服务,即使应用程序关闭,该服务实际上也能够继续。 如果需要,它将重新启动活动。 现在在颤振上有类似的可能吗?

@SirWindfield您最好的选择是使用每个平台的本机媒体播放器API,它将继续与应用程序分开播放。

@kirbyfan64我是这么认为的,谢谢!

@Hixie ,像这样的解决方案(Cordova): https ://github.com/katzer/cordova-plugin-background-mode,或者像这样(Swift): https ://github.com/yarodevuci/backgroundTask 会很好用于 Flutter 后台任务。

@holospeed这些是Apple 可能不会让你发布的方法,所以我猜我们不想花时间自己实现它。 当然,如果您关心 iOS 上的个人应用程序,我们当然欢迎您将其作为社区贡献的包在 pub 上实现。

也许一个解决方案是制作特定的后台插件,例如在后台播放音频的插件,以及在后台的 GPS/Location 插件等,而不是尝试创建需要支持所有内容的抽象背景机制。

是否可以在后台运行计时器,将应用程序带到
某个时间的前景?

在 2018 年 3 月 21 日星期三 08:49,Dylan Drost [email protected]写道:

也许解决方案是制作特定的后台插件,例如
用于在后台播放音频的插件,以及用于 GPS/Location 的插件
在背景等,而不是试图创建一个抽象的背景
需要支持一切的机制。


您收到此消息是因为您订阅了此线程。
直接回复此邮件,在 GitHub 上查看
https://github.com/flutter/flutter/issues/3671#issuecomment-374867947
或使线程静音
https://github.com/notifications/unsubscribe-auth/AK-c-E0KdEkvbH5uCBIM8FaAbYQkSU2tks5tghQWgaJpZM4IVsUk
.

@iBob101我相信如果您将android_alarm_manager插件与android_intent插件结合使用,这是可能的。

在我的用例中,我需要的所有后台任务都是在特定时间在后台播放音频,所以我认为@aegis123建议很棒,我们可以从小处着手,并按时间提供支持任何后台进程的机制

我也需要这个在后台播放音乐。

我一直在研究如何在 android_alarm_manager 插件中完成这项工作,据我所知,通过调用runFromBundle在 Android 上调用了 Dart 代码。 调用的 Dart 函数由入口点指定,但是如果该函数需要传递信息怎么办? 示例用例是一个允许通过通知直接回复的聊天应用程序。 根据此链接,通知将允许远程输入,但似乎不可能将已读取的文本传递给 Dart 函数,以便对其进行处理以便发送回复。

另一个示例是电子邮件应用程序,它在收到新电子邮件时显示通知,可能会显示操作,其中一个可能是归档电子邮件的能力,这是由 Dart 功能完成的。 但是,该功能需要知道哪些电子邮件需要存档。

@MaikuB ,您可以创建一个 PR 以允许传递可以保存键值对的字典。

一般来说,对于我的使用示例,我需要类似于 androids 服务组件的东西。 而且由于 Flutter 并非旨在让每个操作系统都可以提供每个可用的 API,因此在 kotlin/java 或 swift 中编写应用程序实际上可能是一个更好的主意。

我相信@bkonyi目前正在研究我们可以在 iOS 上为这个问题做些什么。

这意味着我们不能使用 Flutter 提供后台服务? 例如:从服务器弹出推送通知的服务。

@s-bauer 始终运行对 Android 来说不是一件事情,除非可能是前台通知,但我没有在您的代码中找到startForeground的提及。

我不确定你的规格是什么,但请记住,安卓手机会在几个小时后进入深度睡眠,屏幕关闭且不移动。 所有服务(前台除外)都将被安排,但操作系统认为这是最好的。 在特定设置下来自 FCM 的推送通知或来自 AlarmManager 的警报可能是开发人员控制下唯一能够在开发人员希望时唤醒 Android 设备/应用程序的两件事,但不是无限量的时间。 还有许多其他方法取决于操作系统认为最适合电池的方法。 有关更多详细信息,请参阅打盹模式。 https://developer.android.com/training/monitoring-device-state/doze-standby

在 iPhone 上,事情受到更多限制。

此外,我不明白为什么服务或连接必须保持活动状态才能接收来自 FCM 或 APNS 的推送通知,也许我遗漏了什么?

快速更新:iOS 的后台执行已实现并等待审核 (PR flutter/engine#5539)。 一旦登陆,我将开始更新 Android 后台执行以具有一致的界面并发布示例插件。 这一切都有望在月底前完成。

@bkonyi这是否也可以通过以下方式解决问题: https ://github.com/flutter/flutter/issues/17566?

@piotrpalek ,是的,它会的,尽管行为可能会与以前有所不同,因为由于各种原因,我们不能再共享 UI 隔离以进行回调。 与前台 UI 的任何通信都必须通过隔离端口、 MethodChannel或任何其他不依赖与主隔离共享内存的方法建立。

状态更新:iOS 和 Android 后台执行更改都在等待审核,并且仍在迭代中。 我预计 Flutter/engine#5539 ​​中的 iOS 更改将在未来几天内登陆,没有任何重大修改请求,并且 Flutter/engine#5640 中的 Android 更改有望在处理评论后的下周完成。 谢谢你的耐心!

惊人的。 是的,我看过 PR,因为他们都提到了这个问题。 你提到做一个示例插件,我看过 iOS 的,会有一个 Android 示例吗? 我猜一旦更改进入, Android 警报管理器插件可能会更新

@MaikuB ,是的,一旦flutter/engine#5640 着陆并且flutter/plugins#642 完成,AlarmManager 插件就会更新。

你好。 有关此主题的任何更新? 决议被推迟到 bucket7 里程碑。 真的会落地吗? 这是我们项目的关键功能。 感谢您的任何回复。

不幸的是,我不得不改变几天的优先事项,但我现在又回到了这个工作上。 我们_几乎_在那里,所以感谢您如此耐心!

现在flutter/engine#5539、flutter/engine#5947和flutter/engine#5954已经落地,Android和iOS后台执行所需的所有功能都在引擎中实现了,应该会在接下来的时间里进入主Flutter存储库发动机滚动。 文档和示例正在编写中, android_alarm_manager插件修复正在等待审查 (flutter/plugins#642)。

@bkonyi 现在android_alarm_manager也可以在 IO 上工作吗?

@ianldgs ,不幸的是没有。 iOS 没有提供任何定期执行代码的机制,因此可能无法创建 iOS 实现(请参阅此SO 帖子)。 通常可以使用一种有限的后台执行模式(例如,重要的位置更改、推送通知、蓝牙状态更改等)来实现相同的目标。

@bkonyi ,这会解决我们目前在 iOS 上长时间(3 分钟)无法执行本机后台任务的问题吗?

为了澄清,这是我们当前的问题......

背景:
我们的应用程序使用蓝牙信标来确定某人在某个位置停留的时间。 我们已经在 AppDelegate.swift 中本地编写了所有的信标代码。

问题:
当我们在被位置事件(在本例中为区域进入/退出)唤醒后在后台执行本机代码时,Flutter 似乎会在几秒钟后关闭我们的应用程序,即使我们正在延长我们的后台执行时间

为什么我们认为它与 Flutter 相关:
我们已经使用原生 iOS 应用程序测试了我们的原生信标代码,并且始终获得 180 秒的后台执行时间没有问题。

我们尝试过的:
我们成功的唯一解决方法是在后台启动我们的应用程序时,在 runApp() 之前的 main() 中延迟 30 秒。 然而,这已经引起了其他问题。

抱歉,对于冗长的解释,但这对我们来说是一个大问题,我们正试图在接下来的几周内发布。

我们真的希望这个修复也能解决我们的问题。

最后,需要明确的是,我们不太关心在后台执行 dart 代码。 相反,我们主要关心的是 Flutter 在后台唤醒时不会过早终止我们的应用程序。

任何帮助将不胜感激。

谢谢!

@AndrewPetrovics不幸的是,我认为这不会解决您看到的问题,因为这些更改主要是为了允许从后台运行 Dart 代码。 我对 iOS 后台执行策略不是很熟悉,但我实际上正在为 Android + iOS 开发一个地理围栏插件,这听起来与你的用例相似,所以我会留意你曾经遇到的问题我今天/明天开始 iOS 部分。

@chinmaygarde ,您是否对@AndrewPetrovics遇到的问题有所了解? 也许这值得提交一个新问题。

@bkonyi ,听起来不错。 我们最终暂时找到了解决方法,但它非常hacky。 当我有机会时,我将创建一个单独的问题。

谢谢!

@bkonyi请问,android_alarm_manager 0.2.0 什么时候会公开部署到 pub.dartlang.org?

@ethael它现在应该可用,只是在等待获得发布更新的权限。

是否有任何可用的示例或一些文档?
谢谢!

@Solban在flutter/plugins 存储库中有两个示例:

我还有一个地理围栏插件正在开发中,它同时支持 Android (Kotlin) 和 iOS (Obj-C),但我不确定它是否会存在于颤振/插件中。

以下是有关后台执行相关功能的一些有用文档:

目前没有关于编写具有后台执行功能的插件的正式文档。 但是,在接下来的几周内,Flutter 博客上应该会出现一篇 Medium 文章,其中将介绍设计、实现和使用利用后台执行的插件的过程。

有什么解决方案可以继续后台工作吗? 在 Android 中持续执行一些长时间运行的代码的唯一正确方法是Foreground service
用例示例将是继续 GPS 位置跟踪。

@audkar目前没有可以处理连续后台工作的插件,但这并不意味着它不能完成。 利用我上面提到的功能与前台服务(而不是我用于地理围栏插件的JobIntentService )的插件可以正常工作。

我目前正在将我的iOS / Android 背景地理定位 / 地理围栏 SDK移植到 Flutter。 它将被称为flutter_background_geolocation

我有大约 5 天的 Dart / Flutter 经验,但我明白了。 它应该会在 2 周内准备好(尽管文档会花费更长的时间来使用 Dart 特定的示例)。

这个 SDK 已经有将近 5 年的历史了,并且是全时支持的。 它最初是为Apache Cordova开发的,后来被移植到React NativeNativeScript 。 它也适用于纯原生应用程序。 在底层,它与每个开发平台使用的核心 Obj-c + Java 库相同。

SDK 最初是为在蜂窝网络可能被破坏的环境中跟踪灾区(例如:飓风、地震)中的急救人员而开发的。 即使应用程序被终止或设备重新启动,它也必须继续跟踪。 该插件包含自己的 SQLite 数据库和 HTTP 服务,用于自动将位置上传到您的服务器。 这对于 Android 来说尤其重要,因为应用程序已被终止,只留下 SDK 的前台服务“无头”运行。

:warning: 这个 SDK 不是为社交应用程序设计的。 它专为“车队跟踪”用例(例如:出租车、送货服务、应急响应、慢跑等)而设计。

这是一个简短的演示视频

经营理念

编辑我还将将另一个库移植为flutter_background_fetch ,它将作为flutter_background_geolocation的依赖项包含在内。 该模块大约每 15 分钟在后台唤醒一个 iOS / Android 应用程序,提供 30 秒的后台时间供您执行周期性工作。 有关详细信息,请参阅react-native版本。

好的,我已经发布flutter_background_geolocation 。 可能还有一些漏洞可以插入到原生库的外观中,并且文档中的示例需要从 React Native 版本翻译。

@christocracy好消息。 后台获取呢? 关于那个的任何估计?

@ethael Fetch 将在大约 2 周后到来。 这是一个非常简单的插件。

@bkonyi我尝试了您的位置更改插件来尝试后台执行。 似乎从无头跑步者执行的飞镖回调不能使用其他插件,失败MissingPluginException

在 Android 上,使用 android_alarm_manager 插件,您可以使用AlarmService.setPluginRegistrant(this);从后台服务内部注册插件来解决此问题。 但我看不到如何为 iOS 实现等价物。

目前是否可以从 iOS 上的无头运行器调用其他插件? 如果是这样,我们如何在这种情况下注册插件?

@bkonyi这个问题没有解决,应该重新打开。 AlarmManager 充其量似乎是一种解决方法,因为它仅支持定时事件。 Flutter 需要更通用的东西,因此您可以监听某些事件,例如范围内的蓝牙设备。 它需要更好地支持iOS。 我知道 iOS 的限制要多得多,但 Flutter 应该支持原生程序员可用的东西。

我很高兴从 Flutter 入手,但似乎有很多类似的问题使得它无法用于除了更简单的应用程序之外的所有应用程序。 我对谷歌的期望更高,我认为他们期望开发人员制作插件来填补他们留下的主要空白是不公平的。

@dude8604谷歌不会提供所有东西是的,由第三方插件开发者(比如我)为生态系统贡献插件。 我自己现在带了两个。

我在 Cordova、React Native 和 NativeScript 上花了很多时间。 在使用 Flutter 2 周后,我认为它非常出色,尽管肯定存在漏洞(例如,跨平台 Map 组件,我相信我会在不久的将来做出贡献。)

在过去的 5 年里,我是一名专业的插件开发人员,专门从事 iOS 和 Android 的后台操作(尤其是地理定位和地理围栏)。 你想知道什么?

@christocracy我同意需要第三方插件,但是后台执行或至少能够为某些事件注册回调函数似乎是应用程序框架应该提供的。 我的问题不在于必须制作插件来扩展核心功能,而是发布一个缺少基本功能的框架,并期望开发人员自愿将时间投入到营利性公司来填补空白。 总之,这里不适合讨论这个。

我想运行一个后台服务并读取某些事件,处理并可能记录数据,如果合适的话,创建一个通知,如果按下它将启动主应用程序。 事件的一些示例包括:范围内的新蓝牙设备、套接字上的传入数据、来自 USB 设备的传入数据、收到短信、GPS 位置更改、蓝牙设备连接尝试、按下某个物理按钮、加速度计数据超过指定的值,如果主应用程序被终止,还有很多我没有想到的其他事情。 如果有人可以为此制作一个适用于 iOS 和 Android 的综合插件(带有免费或开源许可证),我认为这个问题可以关闭。 我会永远感激我可以开始使用 Flutter 进行开发。

@dude8604我想我知道你想要什么。 要做到这一点显然需要一个前台服务,以及它所需的持久通知。 用户知道您正在运行的服务。

通过我的 github 个人资料与我联系。

考虑到 React Native 基本上就像“你得到按钮、文本字段和列表视图,其余的由你决定”,并且由于社区而成长为现在的样子。 Google 不可能处理所有实现,并且认为 Flutter 团队将能够复制 Android 和 iOS 提供的所有功能,当这些功能由 Flutter 大小的 100 倍(10,000 倍?)的团队添加时。

在将android_alarm_managerimage_picker实施到运行Flutter 0.8.3-pre.47的新项目后,它似乎不起作用(如果两者都安装了)。 该应用程序强制关闭。 该示例正在运行,因此我复制了示例中的所有内容并设置了我的 Firebase,但仍然无法正常工作。

要添加@deckerst提出的问题,我不确定在 Android 和 iOS 之间在能够执行使用其他插件的代码方面没有平等的情况下考虑关闭是否合适

编辑:刚刚注意到还有另一个问题要跟踪

只是为了让那些没有看过它的人在这里引用这篇文章:
https://medium.com/flutter-io/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124

谢谢@slightfoot。 确实看到了,这就是我找到让 iOS 无头执行与插件一起工作的票 (#21925) 的地方。 在这两张票之间进行参考会很有用。

在相关说明中,是否有计划将无头执行包含在官方文档中,例如作为食谱的一部分? 我认为是这样,但认为值得一问,因为社区中可能有很大一部分人不知道检查媒介

好点@MaikuB ,为此添加了一个文档错误!

直接在颤振中支持后台,请参阅https://www.youtube.com/watch?v=_LfjILXswJs

我不太明白。 如果 Flutter 现在支持后台执行,为什么教程中大部分都是特定于平台的代码?

获取适用于 Android 的 Outlook https://aka.ms/ghei36


来自:tonka [email protected]
发送时间:2018 年 9 月 21 日星期五凌晨 3:39:28
致:颤动/颤动
抄送:菲利普·韦斯; 提到
主题:回复:[flutter/flutter] Flutter 应该为后台执行提供抽象(#3671)

直接在颤振中支持后台,请参阅https://www.youtube.com/watch?v=_LfjILXswJs


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看https://github.com/flutter/flutter/issues/3671#issuecomment-423490126 ,或将帖子静音https://github.com/notifications/unsubscribe-auth/ABWxFrGMGvfFtwkf025Q2Je6lUTZu2aPks5udMHggaJpZM4IVsUk

@dude8604该教程适用于希望开发插件以执行某些特定后台操作的插件开发人员。

某些特定插件的消费者(尽可能地)对特定于平台的实现视而不见。

因此,作为消费者,如果没有针对我的特定用例的插件,是否有办法在后台运行任意代码?


来自:Chris Scott [email protected]
发送时间:2018 年 9 月 22 日星期六下午 5:43:16
致:颤动/颤动
抄送:菲利普·韦斯; 提到
主题:回复:[flutter/flutter] Flutter 应该为后台执行提供抽象(#3671)

@dude8604 https://github.com/dude8604该教程适用于希望开发插件以执行某些特定后台操作的插件开发人员。

某些特定插件的消费者(尽可能地)对特定于平台的实现视而不见。


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看https://github.com/flutter/flutter/issues/3671#issuecomment-423783230 ,或将帖子静音https://github.com/notifications/unsubscribe-auth/ABWxFhmlurQ08wWXLmMvE3E6yQ_lYvS1ks5udtkkgaJpZM4IVsUk

@dude8604 没有

据我目前所知:

您不会“在后台运行任意代码”。 Android现在很严格。 iOS 一直如此。

@dude8604 ,@ christocracy是正确的。 Medium 文章中展示的后台执行功能面向希望创建可以在后台执行 Dart 代码的插件的开发人员。 大多数 Flutter 用户不必为后台执行编写特定于平台的代码,除非没有与其用例匹配的现有插件,因为这些插件将抽象出 Dart 接口后面的特定于平台的代码。

在将android_alarm_managerimage_picker实施到运行Flutter 0.8.3-pre.47的新项目后,它似乎不起作用(如果两者都安装了)。 该应用程序强制关闭。 该示例正在运行,因此我复制了示例中的所有内容并设置了我的 Firebase,但仍然无法正常工作。

@rupert2133你介意提交一个包含更多信息的问题吗? 请随时提及我,以便我收到通知。 这个问题是针对 Dart 代码后台执行的更广泛的要求,并且已关闭,因此这里的任何额外响应都可能被掩埋。

之后 android_alarm_manager 和 image_picker 似乎不起作用(如果两者都安装了)

这让我想起了。 昨天在我的插件中实现 Headless Android 时,我遇到了来自googlemaps here的错误。

当所有插件都重新注册为 Headless 状态时, registrar.activity() == null

我必须手动破解它才能启动我的应用程序:

public static void registerWith(Registrar registrar) {
    final GoogleMapsPlugin plugin = new GoogleMapsPlugin();
+    Activity activity = registrar.activity();
+    if (activity != null) {
      registrar.activity().getApplication().registerActivityLifecycleCallbacks(plugin);
      registrar
              .platformViewRegistry()
              .registerViewFactory(
                      "plugins.flutter.io/google_maps", new GoogleMapFactory(plugin.state, registrar));
+    }
  }

我怀疑这将是大量插件的问题。

我想运行一个后台服务并读取某些事件,处理并可能记录数据,如果合适的话,创建一个通知,如果按下它将启动主应用程序。 事件的一些示例包括:范围内的新蓝牙设备、套接字上的传入数据、来自 USB 设备的传入数据、收到短信、GPS 位置更改、蓝牙设备连接尝试、按下某个物理按钮、加速度计数据超过指定的值,如果主应用程序被终止,还有很多我没有想到的其他事情。 如果有人可以为此制作一个适用于 iOS 和 Android 的综合插件(带有免费或开源许可证),我认为这个问题可以关闭。 我会永远感激我可以开始使用 Flutter 进行开发。

@bkonyi那么,我目前可以使用现有插件执行上述哪些操作? 我可以使用 AlarmManager 来轮询这些事件吗? 但是 AlarmManager 在 iOS 上不起作用,对吧?

@dude8604对于 iOS 上的定期事件,您将获得的最佳效果是通过“background-fetch”API。 我很快就会移植这个插件来颤振。

iOS“Background Fetch”API 将大约每 15 分钟(这是可能的最快间隔)在后台唤醒一个正在休眠的应用程序,为您的应用程序提供正好30 秒的后台运行时间。 然而,iOS 使用机器学习(大概)并且会根据一天中的时间和设备/应用程序的使用频率来限制它(例如:在晚上,当用户大概在睡觉时,获取事件可能会每小时发生一次。

@christocracy @bkonyi那么所有这些和它们的Android 等价物都可以制作成一个插件吗? 我该如何为此提出功能请求?

@dude8604你不能只挥动魔杖和*poof* 。 你去戴上你的工作手套,自己做。 如果你自己做不到,你就找一个能做的人,然后付给他们数万美元。

@christocracy你是对的,但我希望世界上最大的公司之一能够拥有开发功能齐全的产品的资源,并且不需要其用户花费数万美元来使其足够可用。

嗯,是的,这是一家大公司。

所述公司也由并非无所不在的个人组成。 没有任何框架可以开箱即用地涵盖所有内容,因为如果您尝试,您的项目将变成一堆燃烧的……嗯,垃圾。
有数百个特定于平台的 API,没有一个团队会涵盖它们。 你必须自己绑定一些。

@dude8604考虑到您对“功能齐全”的定义与我的不同。 他们的职责是处理路口。

1 f you write this

我们从文档中有明确的方向吗? 我看到 Release Preview 2 说它支持后台执行。 一些例子会很好。

@Pushan-Gupta 后台执行是插件特定的东西。

这取决于你想做什么。 追踪位置? 接收推送通知? 监控地理围栏? 检测BT设备? 信标? 播放音乐?

没有“一个环来统治他们都支持后台执行”

@christocracy对不起,我不知道。 我的目标是特定的东西。 假设我想从应用程序发出一些帖子请求。 但是连接断开了。 一旦设备重新上线,无论应用程序是否打开,都必须处理这些帖子请求的队列。

示例:Whatsapp 在将消息发送到服务器之前将消息排入队列。 如果设备离线,它会存储队列并在它上线后立即为其提供服务。

顺便说一句,我有一个 PR,讨论后台隔离的插件注册。 如果有人有任何想法...

https://github.com/flutter/engine/pull/6396

目前FlutterHeadlessDartRunner有什么意义?
我目前已经在 Android 上实现了后台执行(没有插件只是FlutterNativeView(ctx, true) ),这有点容易做到。
但是在iOS上它只是崩溃了

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: <strong i="10">@escaping</strong> () -> Void) {
    let headless = FlutterHeadlessDartRunner.init()
    headless.run(withEntrypoint: "main") // just EXC_BAD_ACCESS here
}

嘿,
请帮助 Flutter ios 中的提醒应用

@MohdLucky您需要的帮助是..?

@christocracy你有关于 background_fetch 插件实现状态的更新吗?

不更新 background_fetch 插件的实现状态,请提供一些示例代码
运行后台通知。

对此的任何更新......我真的认为这是颤振的一部分:( ..这与其他网络混合解决方案几乎相同的问题......

@radvansky-tomas 我不知道为什么人们只是不明白这不在颤振的责任范围内。 即使您必须在本地实现后台执行,您仍然拥有单一代码库的优势。 编写一个 Flutter 插件来完成你的后台工作只需要一两天的工作。 我有同样的问题,我需要一个能够为我播放音乐的安卓服务。 我只是用 kotlin 写的,用 Flutter 实现了通信层,后来在 iOS 上也做了同样的事情。
完全可以只使用系统原生后台系统。
而不是在这里抱怨 X 没有实现,你可以使用团队提供的生态系统毫无问题地实现它。

@SirWindfield不幸的是你不知道你在说什么。 这是架构的重要组成部分,而不是插件本身。

Flutter 被呈现为生成本机代码的跨平台解决方案,即期望它可以在每次操作系统允许的情况下运行其语言 (Dart) 的代码。

因此,如果应用程序在收到远程通知后正在运行,并且您可以在现有的本机代码中放置断点,您应该能够调用您的颤振/飞镖代码,您的服务、模型和最终 UI 在哪里。

为了适应您的情况...假设您的音乐正在后台播放,然后您完成播放列表... 10 分钟后是您的应用程序关闭。 然后你打电话给 siri,或者使用耳机再次开始播放你的应用程序,无论你选择什么入口点......本机代码被执行,但不是它的 UI,你的颤动代码没有初始化,你丢失了我的通知。

所以不,这是不可能的,我可以为我编写本机插件捕获通知,但是我需要访问颤振业务逻辑来处理数据,在我的情况下加密解密并发布带有解密内容的本地通知

我们会的,我已经在我的手机上对其进行了广泛的测试,它可以毫无问题地工作。
可能是我的手机从未杀死该应用程序。 那我的坏。

@christocracy关于 background_fetch 插件克里斯的任何更新?

@ethael这是供您查看更新的空仓库。
https://github.com/transistorsoft/flutter_background_fetch

@radvansky-tomas 您可以通过创建后台隔离来处理 Dart 代码中的后台事件,如这篇关于后台执行的 Medium 帖子中所述。 您可能需要为每个平台编写一些本机代码以满足您的特定需求,除非已经存在一个插件可以满足您的需求(不太可能,因为我不知道目前有许多插件支持后台执行)。

@bkonyi感谢您的回复,我开始更改 firebase_messaging 插件以支持后台执行...但是这个问题更多的是关于一些通用的方法。 我的意思是它应该是 template = runner 及其 dart 方面的一部分,开发人员可以在其中执行这样的无头代码、一些规则、模式标准,因为现在遍布一些博客、建议等。

完成了一些初步工作: https ://github.com/radvansky-tomas/plugins/tree/master/packages/firebase_messaging

遵循https://github.com/bkonyi/FlutterGeofencing的一些指南

我应该在本周末完成它,我现在只在 iOS 上工作。 示例项目使用本地通知插件来显示在后台收到消息(静默通知),然后发布新的本地通知,以显示成功。

完成了一些初步工作: https ://github.com/radvansky-tomas/plugins/tree/master/packages/firebase_messaging

遵循https://github.com/bkonyi/FlutterGeofencing的一些指南

我应该在本周末完成它,我现在只在 iOS 上工作。 示例项目使用本地通知插件来显示在后台收到消息(静默通知),然后发布新的本地通知,以显示成功。

@goderbauer和我实际上希望添加这种支持,但如果您计划提出拉取请求,我们将非常乐意帮助您进行设计和审查。

所以我几乎完成了那部分,所以现在我可以接收静默推送通知,并且我用 dart 编写的回调在应用程序处于后台时执行。

但是,我无法访问那里的任何其他插件。 回调必须是根/静态方法,并且真的不知道如何从那里调用任何东西。

所以我尝试做一个简单的测试,在收到静默通知后使用flutter本地通知插件发送本地通知,但插件似乎无法访问(未注册?)

我在这里找到了类似的帖子: https ://github.com/flutter/engine/pull/6396

是否有任何其他必要的步骤,我必须加载这些插件?

我的根级回调:
void callback(FirebaseMessage m, MessageEvent e) async { print('Message $m Event: $e'); final SendPort send = IsolateNameServer.lookupPortByName('messaging_send_port'); send?.send(e.toString()); }

问题不是如何从该回调访问所有 dart 代码 + 插件...查询 firestore 等

我的后台获取实现终于发布了。
background_fetch

@christocracy你是对的,但我希望世界上最大的公司之一能够拥有开发功能齐全的产品的资源,并且不需要其用户花费数万美元来使其足够可用。

这是真的。 如果你得到人们的时间,你应该回馈他们一些东西。 如果没有,那么不要制作这些花哨的营销标题!

似乎这个问题仍在引起人们的困扰? 它已经关闭并且有很多评论,所以我们不太可能从这个问题上做出许多具体的项目更改。 :((我们需要提交新的文件才能取得我期望的更多进展。)

我会对我们在这里记录所需的具体更改非常感兴趣。 听起来需要更多背景示例? (例如 https://github.com/flutter/flutter/issues/23794)

无论如何,我们很乐意将个别问题与个别要求一起提交。 正如其他人在上面提到的那样,Flutter 是一个庞大而复杂的项目,尽管我们在 Google 拥有一支庞大(且迅速扩张的)团队,但我们仍然没有足够的工程师全职从事 Flutter 以同时解决所有问题。 Flutter 是 100% 开源的,我们所有的问题都在 GitHub 上。 当然,补丁总是受欢迎的。 :)

对于任何需要的问题/更改,请提交新问题,让所有贡献者知道我们可以如何进一步提供帮助: https ://github.com/flutter/flutter/issues/new

谢谢!

接受@eseidel挑战:#24278

我希望避免编写特定于设备的代码,并让 Flutter Dart API 实现可能基于隐藏设备和操作系统规范和特定实现的事件。

已经在这里解决了

@Krunal79-flutter 究竟如何,这种方法仍然存在同样的问题。 问题是,在您的场景中,颤振已经初始化,然后它的后台访问权限不正确。 我所拥有和拥有的问题是,当应用程序实际上已死并且静默通知(或应用程序扩展)将唤醒您的应用程序并且您需要在颤振尚未运行时执行“飞镖”逻辑(即不存在 UI)。

对于管理 Flutter 团队的人来说,这确实应该是一个更高优先级的问题。 实现后台功能对于普通的 Flutter 开发人员来说是一个巨大的痛苦,而且它经常以非平凡的方式崩溃。 我相信很多应用程序开发人员目前都在为此苦苦挣扎。

@tomoerlemans010请参阅https://github.com/flutter/flutter/issues/3671#issuecomment -438113161 中的评论。

此特定问题已关闭,请对与后台执行相关的其他未解决问题添加评论,或使用您面临的问题创建一个新问题。

此页面是否有帮助?
0 / 5 - 0 等级