Android Alarm Manager回调不起作用

时间:2019-04-09 18:44:49

标签: flutter dart-isolates

我正在尝试使用插件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行:”:“回调”不得为空。”

1 个答案:

答案 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"),
        );
  }