如何使用 flutter 和 alarmManager 从后台代码启动 ui?
How to start an ui from background code with flutter and alarmManager?
我在后台代码中使用 AlarmManager 运行 代码但是。我需要在这段代码中启动 UI(比如调用通知或给智能手机响铃)。我想知道该怎么做?我知道如何 运行 后台任务但不知道如何开始 UI.
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:relax/pages/intro.dart';
import 'package:relax/pages/splash_screen.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
void printHello() {
final DateTime now = new DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
void main() async {
await AndroidAlarmManager.initialize();
final int helloAlarmID = 0;
runApp(new MyApp());
await AndroidAlarmManager.periodic(const Duration(seconds: 15), helloAlarmID, printHello);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(title: 'Flutter Demo', initialRoute: '/', routes:
{
'/': (context) => SplashScreen(),
'/intro': (context) => IntroPage(),
});
}
}
在 official docs (Medium article here) 之后,Flutter 中的背景 Isolates 有一个无头的 FlutterNativeView,所以你永远无法从背景 Isolate 中绘制任何东西。地理围栏示例显示了两个选项:
让您的主 Isolate 向 IsolateNameServer 注册一个 SendPort。请参阅示例 here。这在实践中可能毫无价值,因为当 Activity 在后台经过任何有意义的时间后被杀死时(或者如果用户明确关闭它),SendPort 将被销毁。
让后台 Isolate 显示通知。请参阅示例 here。当与通知交互时,FlutterLocalNotifications 将启动你的 main/UI Isolate。如果通知被取消,或者您需要在精确的闹钟时间通知以外的其他内容,您现在可能不走运。
请注意,Isolate 之间的可靠通信基本上为零,因此如果您依赖任何共享数据,则必须发挥创造力。
最后请注意,您可能需要升级到最新版本的 Flutter (>=1.12) 以解决一些插件注册问题。将以下内容添加到您的 Android 清单中 Activity:
<activity>
...
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
我在后台代码中使用 AlarmManager 运行 代码但是。我需要在这段代码中启动 UI(比如调用通知或给智能手机响铃)。我想知道该怎么做?我知道如何 运行 后台任务但不知道如何开始 UI.
import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:relax/pages/intro.dart';
import 'package:relax/pages/splash_screen.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
void printHello() {
final DateTime now = new DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
void main() async {
await AndroidAlarmManager.initialize();
final int helloAlarmID = 0;
runApp(new MyApp());
await AndroidAlarmManager.periodic(const Duration(seconds: 15), helloAlarmID, printHello);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(title: 'Flutter Demo', initialRoute: '/', routes:
{
'/': (context) => SplashScreen(),
'/intro': (context) => IntroPage(),
});
}
}
在 official docs (Medium article here) 之后,Flutter 中的背景 Isolates 有一个无头的 FlutterNativeView,所以你永远无法从背景 Isolate 中绘制任何东西。地理围栏示例显示了两个选项:
让您的主 Isolate 向 IsolateNameServer 注册一个 SendPort。请参阅示例 here。这在实践中可能毫无价值,因为当 Activity 在后台经过任何有意义的时间后被杀死时(或者如果用户明确关闭它),SendPort 将被销毁。
让后台 Isolate 显示通知。请参阅示例 here。当与通知交互时,FlutterLocalNotifications 将启动你的 main/UI Isolate。如果通知被取消,或者您需要在精确的闹钟时间通知以外的其他内容,您现在可能不走运。
请注意,Isolate 之间的可靠通信基本上为零,因此如果您依赖任何共享数据,则必须发挥创造力。
最后请注意,您可能需要升级到最新版本的 Flutter (>=1.12) 以解决一些插件注册问题。将以下内容添加到您的 Android 清单中 Activity:
<activity>
...
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />