Biểu thức boolean không được rỗng?

Aug 31 2020

Có ai biết tại sao tôi nhận được khẳng định không thành công: biểu thức boolean không được rỗng. Nếu tôi đã đăng nhập và thoát khỏi ứng dụng và mở lại ứng dụng, tôi sẽ ở ngay màn hình chính.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {

  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  bool userIsLoggedIn = false;

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

  getLoggedInState()async{
    await HelperFunction.getUserLoggedInSharedPreference().then((value){
      setState(() {
        userIsLoggedIn = value;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: userIsLoggedIn ? HomeScreen() : CompanyLoadingBar(),
    );
  }
}

Trả lời

2 galloper Aug 31 2020 at 10:37

Nếu 'giá trị' của bạn ở đây có thể trở thành null - bạn sẽ gặp lỗi. Để an toàn, hãy thay đổi dòng bên trong setState thành:

userIsLoggedIn = value ?? false; 

nó sẽ đặt bool thành false nếu giá trị là null

nvoigt Aug 31 2020 at 10:47

Vấn đề của bạn là bạn không chờ đợi Tương lai của bạn giải quyết thành giá trị thực tế.

Đường thẳng này:

userIsLoggedIn = value;

có thể không đạt được khi phương thức xây dựng của bạn được gọi. Bởi vì nó asyncvà bạn không awaitnó.

Bạn có thể đặt giá trị mặc định thành userIsLoggedIn, có thể false, điều đó sẽ giải quyết được vấn đề trước mắt của bạn. Nhưng nó sẽ không giải quyết được vấn đề thực sự của bạn, rằng logic chương trình của bạn là không đồng bộ.

Bạn có thể sẽ muốn xây dựng ứng dụng của mình với ít nhất một ứng dụng FutureBuilder.

Xem: Tương lai là gì và tôi sử dụng nó như thế nào?

Benjamin Aug 31 2020 at 10:33

Vấn đề của bạn rất có thể nằm ở chức năng này, nơi bạn đang đặt userIsLoggedInthành null. Đảm bảo getUserLoggedInSharedPreferencethực sự trả về boolean chứ không phải null.

  void getLoggedInState() async {
    final result = await HelperFunction.getUserLoggedInSharedPreference();
    if (result != null) {
      setState(() {
        userIsLoggedIn = result;
      });
    } else {
      print("result is null");
    }
  }
BambinoUA Sep 11 2020 at 08:07

Bạn có một lỗi tiếp cận toàn cầu. Bạn kết hợp traditionalasync/awaitcác phương pháp trong mã này:

getLoggedInState()async{
    await HelperFunction.getUserLoggedInSharedPreference().then((value){
      setState(() {
        userIsLoggedIn = value;
      });
    });
  }

Nếu bạn sử dụng async/awaitbạn không nên sử dụng thenphương pháp.

Để thực hiện những gì bạn muốn, bạn nên sử dụng một cái gì đó như sau:

...
@override
Widget build(BuildContext context) {
  return MaterialApp(
    debugShowCheckedModeBanner: false,
    home: FutureBuilder<bool>(
      future: HelperFunction.getUserLoggedInSharedPreference(),
      builder: (context,snapshot) {
        if (snapshot.hasData) {
          // Future is ready. Take data from snapshot
          userIsLoggedIn = snapshot.data; // bool value is here
          return userIsLoggedIn ? HomeScreen() : CompanyLoadingBar();
        } else {
          // Show progress while future will be completed
          return CircularProgressIndicator();
        }
      }
    ),
  );
}
...

Và cũng kiểm tra xem giá trị được trả về từ đâu HelperFunction.getUserLoggedInSharedPreference(). Có vẻ như nó trả về nullvì tôi nghĩ rằng bạn chưa có giá trị đã lưu. Vì vậy, bạn cần chỉ định giá trị mặc định:

final value = await SharedPreferences.getInstance().readBool(name) ?? false;