如何从 Future<bool> 中获取 'bool' 值到字段变量中,以备后用

How to get the 'bool' value from a Future<bool> into a field variable, for later use

我正在使用 flutter_blue 包来使用蓝牙服务。我想检查设备是否具有蓝牙功能。方法 isAvailable 似乎可以做到。然而,它 returns 一个 Future,我正试图将其放入一个变量中,如下所示:

import 'package:flutter_blue/flutter_blue.dart';

class BT_Base {

final FlutterBlue _fb = FlutterBlue.instance;
bool BTAvailable = true;     // as a default placeholder

BT_Base () {
    BTAvailable = _fixAvail();
}

_fixAvail () async {
  return await _fb.isAvailable;
}

...

我尝试从中获取未来值并存储到 BTAvailable。稍后,我使用固定的 BTAvailable 字段来获取要传递到的适当的 Widget,如下所示:

class BTDevicePrompt extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    BT_Base bt = BT_Base();
    var btDeviceRes = bt.scan();

    if(!bt.BTAvailable) return Text('Bluetooth unavailable on device...');
    else if (btDeviceRes.isEmpty) return Text('No Bluetooth devices in range...');
    else {
      return CupertinoActionSheet(
        actions: [
                  ...
                 ],
      )
    }
  }
}

但我在运行时不断收到错误 type 'Future<dynamic>' is not a subtype of type 'bool'。在这种情况下如何正确使用 Future?如果整个过程只是暂停并等待这部分也可以。

我已经尝试了很多解决方案,但我无法将它们拼凑起来。

任何标记为 async 的方法总是 return 是某种 Future。你可以给它一个明确的 return 类型,比如 Future<bool> function() async { ... },或者如果你不加它,它会推断出 Future<dynamic>.

简而言之,你不能从 async 函数之外的 Future<bool> 得到 bool (技术上有方法,但几乎可以肯定不是你在 Flutter 中想要的) .

这是有道理的,因为 Future<bool> 的全部意义在于它将成为 bool 将来 。如果有一个从Future<bool>转换为bool的过程,如果future还没有完成怎么办?也许它应该等到它完成。在这种情况下,您只是在描述 await 关键字。

但是,如果您想在 Flutter 应用程序的 UI 中使用 Future,您有几个选择。

最简单的方法是将其移至 initState():

class BTDevicePrompt extends StatefulWidget {
  // stateful widget boilerplate
}

class BTDevicePromptState extends State<BTDevicePrompt> {
  bool isAvailable = false;

  @override
  void initState() {
    super.initState();
    checkAvailable();  // use a helper method because initState() cannot be async
  }

  Future<void> checkAvailable() async {
    // call an async function and wait for it to complete
    bool result = await checkIfBluetoothAvailable();
    setState(() => bluetoothAvailable = result);  // set the local variable
  }

  @override
  Widget build(BuildContext context) {
    if (bluetoothAvailable) return Text('bluetooth available');
    else return Text('bluetooth not available');
  }
}