flutter 如何在全局函数中使用setState()?

qyswt5oh  于 2023-02-20  发布在  Flutter
关注(0)|答案(1)|浏览(204)

下面是一个简单的代码块,用于检测来自SMS的交易:

FlutterLocalNotificationsPlugin notificationsPlugin =
    FlutterLocalNotificationsPlugin();

onBackgroundMessage(SmsMessage message) async {
  log("Message recieved in background");
  _TransactionState().onMessage(message);
}

class Transaction extends StatefulWidget {
  const Transaction({Key? key}) : super(key: key);

  @override
  State<Transaction> createState() => _TransactionState();
}

class _TransactionState extends State<Transaction> {
  String _message = "";
  var debit = 0.0;
  var credit = 0.0;
  var last = 0.0;
  var transact = 0.0;
  final Telephony telephony = Telephony.instance;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  onMessage(SmsMessage message) async {
    setState(() {
      bool mesFlag = false;
      bool debFlag = false;
      if (message.body!.contains('debit')) {
        debFlag = true;
      } //check whether debit or credit
      for (var bank in banks.entries) {
        if (message.address!.contains(bank.key)) {
          _message = message.body?.split(
                  ' ')[(debFlag ? bank.value.item2 : bank.value.item1)] ??
              "Error reading transaction!";
          _message = _message.replaceAll(',', ''); //remove comma
          if (_message.contains("Rs.")) {
            _message = _message.substring(3);
          } else if (_message.contains("Rs")) {
            _message = _message.substring(2);
          } // remove Rs. and Rs
          showNotification("Last transaction amount: $_message");
          transact = double.parse(_message);
          mesFlag = true;
          if (debFlag) {
            debit += transact;
            last = -transact;
          } else {
            credit += transact;
            last = transact;
          }
          limit += last;
          if (limit < 0) {
            limit = 0;
            showNotification("You are over-spending!");
          }
          transList.add(TransactionTile(trans: last));
          break;
        }
      }
      if (!mesFlag) _message = ''; //if not a transaction
    });
  }

下面是我在后台收到短信时抛出的异常:

setState() called in constructor: _TransactionState#f0921(lifecycle state: created, no widget, not mounted)
This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.

电话软件包要求onBackgroundMessage是一个全局函数。是否有任何变通办法,通过它我可以调用全局函数中的onMessagesetState(),因为我需要他们被更新,即使当应用程序没有打开&它应该完全像onMessage功能。
任何帮助都感激不尽。

63lcw9qa

63lcw9qa1#

从Firebase云消息传递Flutter文档中获取有关背景消息的信息:
由于处理程序在应用程序上下文之外独立运行,因此无法更新应用程序状态或执行任何影响UI的逻辑。但是,您可以执行HTTP请求等逻辑、执行IO操作(例如更新本地存储)、与其他插件通信等。
只有当用户决定单击包含消息的通知并且应用程序从后台转到前台时,您才可以执行影响UI的逻辑。
如果您不想在应用再次激活时静默接收某些数据并更新UI,您可以执行以下操作:

  • 将数据保存在共享首选项中,您可以从onBackgroundMessage访问该首选项,
  • 实现didChangeAppLifecycleState覆盖,以便在激活应用程序并相应更新UI时检查共享首选项中的数据。

相关问题