不要跨异步间隙使用 BuildContexts flutter

6 async-await dart flutter

我已经创建了一个注册函数,但收到一条警告,Do not use BuildContexts across async gaps.提示Utils.flushBarErrorMessage("No Internet", context);我是 flutter 新手,想知道如何使用asyncawait

Future _registration() async {
    String name = _nameController.text.trim();
    String email = _emailController.text.trim();
    String password = _passwordController.text.trim();
    String phone = _phoneController.text.trim();

    if (name.isEmpty) {
      Utils.flushBarErrorMessage("Type your name", context);
    } else if (email.isEmpty) {
      Utils.flushBarErrorMessage("Type your email", context);
    } else if (!GetUtils.isEmail(email)) {
      Utils.flushBarErrorMessage("Type valid email address", context);
    } else if (password.isEmpty) {
      Utils.flushBarErrorMessage("Type your password", context);
    } else if (password.length < 6) {
      Utils.flushBarErrorMessage(
          "password can't be less than 6 characters", context);
    } else if (phone.isEmpty) {
      Utils.flushBarErrorMessage("Type your phone", context);
    }
    else {
      var connectivityResult = await (Connectivity().checkConnectivity());
      if (connectivityResult == ConnectivityResult.mobile ||
          connectivityResult == ConnectivityResult.wifi) {
        ApiCall.signUp(name, email, password, phone).then((value) {
          if (value.statusCode == 200) {
            if (json.decode(value.body)['success'] != null) {
              if (json.decode(value.body)["success"]) {
                RegisterResponse registerResponseModel =
                    RegisterResponse.fromJson(json.decode(value.body));
                Navigator.pushNamed(context, VerifyUser.routeName);
                Utils.flushBarErrorMessage(
                    'User Registered Successfully', context);
                if (kDebugMode) {
                  print('User Registered Successfully');
                }
              } else {
                Utils.flushBarErrorMessage(
                    json.decode(value.body)["en_message"], context);
                if (kDebugMode) {
                  print(json.decode(value.body).toString());
                }
              }
            }
          } else {
            Utils.flushBarErrorMessage('invalid data', context);
            if (kDebugMode) {
              print(json.decode(value.body).toString());
            }
          }
        });
      } else {
        Utils.flushBarErrorMessage("No Internet", context);
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

称这个_registration()

ElevatedButton(
            onPressed: () {
              _registration();
            },
            child: const Text('SignUp')),
Run Code Online (Sandbox Code Playgroud)

这是我的flushBarErrorMessage

   class Utils {
  static void flushBarErrorMessage(String message, BuildContext context) {
    showFlushbar(
        context: context,
        flushbar: Flushbar(
          forwardAnimationCurve: Curves.decelerate,
          margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
          padding: const EdgeInsets.all(15),
          titleColor: Colors.white,
          duration: const Duration(seconds: 3),
          borderRadius: BorderRadius.circular(10),
          reverseAnimationCurve: Curves.easeInOut,
          icon: const Icon(
            Icons.error,
            size: 28,
            color: Colors.white,
          ),
          flushbarPosition: FlushbarPosition.TOP,
          positionOffset: 20,
          message: message,
          backgroundColor: Colors.red,
        )..show(context));
  }
}
Run Code Online (Sandbox Code Playgroud)

lep*_*sch 8

问题是,在 后await,每次使用BuildContext都会显示此警告。出现此警告是因为在小部件被处理后可能会发生使用BuildContextafter an 的情况。await这样,上下文将不再存在,应用程序甚至可能因此崩溃。查看官方 lint 文档

存储 BuildContext 以供以后使用很容易导致难以诊断的崩溃。异步间隙隐式存储 BuildContext,并且是编写代码时最容易忽视的一些间隙。

从官方文档来看,简单的解决方案是需要检查State.mounted. 在警告出现的每个地方,代码看起来都是这样的:

      ...
      } else {
        if (mounted) Utils.flushBarErrorMessage("No Internet", context);
      }
      ...
Run Code Online (Sandbox Code Playgroud)