首页 > 解决方案 > 不可为空的实例字段必须初始化和未处理的错误 LateInitializationError

问题描述

我正在尝试创建一个数据库并存储一个 API 令牌以供用户登录,但是当应用程序构建/编译时我不断收到错误消息:

必须初始化不可为空的实例字段“_database”

我尝试按照建议添加一个后期修饰符,然后抛出:

E/flutter(6894):[错误:flutter/lib/ui/ui_dart_state.cc(199)]未处理的异常:未处理的错误LateInitializationError:字段'_database@637109567'尚未初始化。发生在“AuthenticationBloc”的实例中。

我的 user_db.dart

import 'dart:io';

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';

final userTable = 'userTable';



class DatabaseProvider {
  static final DatabaseProvider dbProvider = DatabaseProvider();
  //non nullable error on _database
  Database _database;

  Future <Database> get database async {

    print('before condition');
    if (_database != null){
      return _database;
    }
    _database = await createDatabase();
    return _database;
  }

  createDatabase() async {
    Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "User.db");

    var database = await openDatabase(
      path,
      version: 1,
      onCreate: initDB,
      onUpgrade: onUpgrade,
    );
    return database;
  }

  void onUpgrade(
      Database database,
      int oldVersion,
      int newVersion,
      ){
    if (newVersion > oldVersion){}
  }

  void initDB(Database database, int version) async {
    await database.execute(
        "CREATE TABLE $userTable ("
            "id INTEGER PRIMARY KEY, "
            "username TEXT, "
            "token TEXT "
            ")"
    );
  }
}

我的 AuthBloc.dart

import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'package:equatable/equatable.dart';

import 'package:times/repository/user_repository.dart';
import 'package:times/model/user_model.dart';

part 'authentication_event.dart';
part 'authentication_state.dart';

class AuthenticationBloc
    extends Bloc<AuthenticationEvent, AuthenticationState> {

  AuthenticationBloc({required this.userRepository})
      : super(AuthenticationUnauthenticated())
  ;

  final UserRepository userRepository;

  @override
  Stream<AuthenticationState> mapEventToState(
    AuthenticationEvent event,
  ) async* {
    if (event is AppStarted) {

      final bool hasToken = await userRepository.hasToken();

      if (hasToken) {
        yield AuthenticationAuthenticated();
      } else {
        yield AuthenticationUnauthenticated();
      }
    }

    if (event is LoggedIn) {
      yield AuthenticationLoading();

      await userRepository.persistToken(
        user: event.user
      );
      yield AuthenticationAuthenticated();
    }

    if (event is LoggedOut) {
      yield AuthenticationLoading();

      await userRepository.deleteToken(id: 0);

      yield AuthenticationUnauthenticated();
    }
  }
}

标签: flutterdart

解决方案


问题是由这条线引起的

if (_database != null) {

您不能直接对不可为空的变量应用空检查,并且由于它是一个late变量并且您没有对其进行初始化,因此空检查将始终抛出错误。

解决此问题的一种方法是使您的_databaseNullable 并将其实例化为null,像这样

Database? _database = null;

为了避免Nullable在代码中到处使用类型,您可以修改您的函数以使用bang运算符 ( !),如下所示,

Future <Database> get database async {
  if (_database != null){
    return _database!;
  }
  _database = await createDatabase();
  return _database!;
}

推荐阅读