我正在尝试使用插件Android Alarm Manager在后台执行计时器和代码,但实际上无法使其正常工作。如果我将诸如“ print(” v“)”之类的内容设置为回调-一切正常,但是当我试图做一些额外的事情时,它就行不通了。
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'dart:isolate';
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
startTimer(sendport) async {
await AndroidAlarmManager.oneShot(
Duration(seconds: 60), 0, timerCallback(sendport),
wakeup: true, exact: true);
}
timerCallback(sendport) {
sendport.send("DONE");
}
class _MyAppState extends State<MyApp> {
ReceivePort receivePort = ReceivePort();
SendPort sendport;
@override
void initState() {
super.initState();
AndroidAlarmManager.initialize();
receivePort.listen((v) {
print(v);
});
}
@override
Widget build(BuildContext context) {
RaisedButton(
onPressed: startTimer(sendport),
child: Text("Start"),
);
}
}
我希望该代码在1分钟后发送消息,而不是在执行后立即获取消息并出现错误 “ / flutter(11424):[ERROR:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:'dart:ui / plugins.dart':失败的断言:第62行:”:“回调”不得为空。”
答案 0 :(得分:0)
隔离组织可以通过使用IsolateNameServer注册并查找姓名来相互查找
您需要为主隔离符和回调都可以看到的端口名称,全局常量似乎可以正常工作。
传递给 AlarmManager.oneShot 的计时器回调没有参数,因此它需要查找端口名称以查找运行时要使用的SendPort。
设置时注册主要隔离区的SendPort的端口名-您仍然需要 MyAppState 中的ReceivePort,但是不需要SendPort。
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'dart:isolate';
import 'dart:ui';
const String portName = "MyAppPort";
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
startTimer() async {
await AndroidAlarmManager.oneShot(
Duration(seconds: 60), 0, timerCallback,
wakeup: true, exact: true);
}
timerCallback() {
SendPort sendPort = IsolateNameServer.lookupPortByName(portName);
if (sendPort != null) {
sendport.send("DONE");
}
}
class _MyAppState extends State<MyApp> {
ReceivePort receivePort = ReceivePort();
@override
void initState() {
super.initState();
IsolateNameServer.registerPortName(receivePort.sendPort, portName)
AndroidAlarmManager.initialize();
receivePort.listen((v) {
print(v);
});
}
@override
Widget build(BuildContext context) {
RaisedButton(
onPressed: startTimer(),
child: Text("Start"),
);
}