Flutter, "LateInitializationError: Field '_alarmHelper@808171109' has not been initialized."

Flutter, "LateInitializationError: Field '_alarmHelper@808171109' has not been initialized."

我收到“LateInitializationError:字段‘_alarmHelper@808171109’尚未初始化。”每当我尝试在 flutter 中初始化我的数据库时。

您可以在下面找到完整的错误本身:

    ======== Exception caught by widgets library =======================================================
The following LateError was thrown building Builder:
LateInitializationError: Field '_alarmHelper@808171109' has not been initialized.

The relevant error-causing widget was: 
  MaterialApp MaterialApp:file:///C:/Users/shant/StudioProjects/weather_alarm_app/lib/main.dart:37:12
When the exception was thrown, this was the stack: 
#0      AlarmHelper._alarmHelper (package:weather_alarm_app/alarm_helper.dart)
#1      new AlarmHelper (package:weather_alarm_app/alarm_helper.dart:18:9)
#2      new _AddAlarmScreenState (package:weather_alarm_app/add_alarm_screen.dart:29:30)
#3      AddAlarmScreen.createState (package:weather_alarm_app/add_alarm_screen.dart:24:41)
#4      new StatefulElement (package:flutter/src/widgets/framework.dart:4675:25)
#5      StatefulWidget.createElement (package:flutter/src/widgets/framework.dart:737:38)
...     Normal element mounting (169 frames)
#174    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3631:14)
#175    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6254:36)
#176    Element.updateChild (package:flutter/src/widgets/framework.dart:3383:18)
#177    RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5679:32)
#178    MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6277:17)
#179    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#180    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#181    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4761:11)
#182    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#183    StatefulElement.update (package:flutter/src/widgets/framework.dart:4793:5)
#184    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#185    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#186    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#187    ProxyElement.update (package:flutter/src/widgets/framework.dart:4941:5)
#188    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#189    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#190    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#191    ProxyElement.update (package:flutter/src/widgets/framework.dart:4941:5)
#192    _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:111:11)
#193    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#194    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6123:14)
#195    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#196    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#197    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4761:11)
#198    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#199    StatefulElement.update (package:flutter/src/widgets/framework.dart:4793:5)
#200    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#201    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6123:14)
#202    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#203    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6123:14)
#204    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#205    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#206    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#207    ProxyElement.update (package:flutter/src/widgets/framework.dart:4941:5)
#208    Element.updateChild (package:flutter/src/widgets/framework.dart:3370:15)
#209    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4611:16)
#210    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4761:11)
#211    Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#212    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2578:33)
#213    WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#214    RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5)
#215    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1145:15)
#216    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1082:9)
#217    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#221    _invoke (dart:ui/hooks.dart:150:10)
#222    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#223    _drawFrame (dart:ui/hooks.dart:114:31)
(elided 3 frames from dart:async)

这是每当我尝试初始化时抛出错误的屏幕代码。

class AddAlarmScreen extends StatefulWidget {
  const AddAlarmScreen({Key? key}) : super(key: key);
  @override
  _AddAlarmScreenState createState() => _AddAlarmScreenState();
}

class _AddAlarmScreenState extends State<AddAlarmScreen> {

  AlarmHelper _alarmHelper = AlarmHelper();
  
  @override
  void initState() {
    print(DateTime.now());
    _alarmHelper.initializeDatabase().whenComplete(() => print('-----dB initialized'));
    super.initState();
  }
  
  
  
  // Methods
  String getDate(){
    if (date == null) return 'Select Date';
    else{
      return "${date.day}/${date.month}/${date.year}";
    }
  }
  String getTime(){
    if (time == null) return 'Select Time';
    else{
      var minute  = time.minute.toString().padLeft(2, '0');
      var hour  = time.hour.toString().padLeft(2, '0');
      return "$hour:$minute";
    }
  }

  void showErrorDateFlash({
    Duration? duration,
    flashStyle = FlashBehavior.floating,
    String? text,
  }) {
    showFlash(
      context: context,
      duration: duration,
      builder: (context, controller) {
        return Flash(
          controller: controller,
          behavior: flashStyle,
          position: FlashPosition.bottom,
          boxShadows: kElevationToShadow[4],
          horizontalDismissDirection: HorizontalDismissDirection.horizontal,
          child: FlashBar(
            content: Center(child: Text(text!)),
          ),
        );
      },
    );
  }

  Future pickDate(BuildContext context) async {
    final initialDate = DateTime.now();
    final newDate = await showDatePicker(context: context, initialDate: date == null ? initialDate : date, firstDate: DateTime(DateTime.now().year), lastDate: DateTime(DateTime.now().year + 5));

    if(newDate == null) return;
    if(newDate.isBefore(DateTime.now()))
    {
      showErrorDateFlash(duration: Duration(seconds: 10), text: 'Date Invalid. Please try again!');
      return;
    }
    setState(() {
      date = newDate;
    });
  }

  Future pickTime(BuildContext context) async {
    final newTime = await showTimePicker(context: context, initialTime: TimeOfDay.now());

    if(newTime == null) return;
    setState(() {
      time = newTime;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: (){
        DateTime finalDateTime =  DateTime(date.year, date.month, date.day, time.hour, time.minute);


        var alarmInfo  = AlarmInfo( title: title, dateTime: finalDateTime, gradientColorIndex: alarms.length, id: alarms.length, isPending: true);


      }, child: Icon(Icons.add,),),
      backgroundColor: Color(0xff2E2E42),
      appBar: PreferredSize(preferredSize: Size.fromHeight(50),
          child: CustomAppBar("Add Alarm")),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 42.0, vertical: 10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Enter title for the Alarm:', style: CustomTextStyle.customTextStyle(20),),
            TextField(
              onChanged: (text){
                title = text;
              },
              style: CustomTextStyle.customTextStyle(15),
            ),
            MaterialButton(onPressed: (){pickDate(context);},
              padding: EdgeInsets.zero,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text('Select Date:', style: CustomTextStyle.customTextStyle(20),),
                  Center(
                    child: Text(getDate(), style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),),
                  ),
                ],
              ),),
            MaterialButton(onPressed: (){pickTime(context);},
              padding: EdgeInsets.zero,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text('Select Time:', style: CustomTextStyle.customTextStyle(20),),
                  Center(
                    child: Text(getTime(), style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),),
                  ),
                ],
              ),)
          ],
        ),
      ),
    );
  }
}

这是 AlarmHelper 的代码:

import 'package:sqflite/sqflite.dart';
import 'package:weather_alarm_app/models/alarm_info.dart';


final String tableName = 'alarm';
final String id = 'id';
final String title = 'title';
final String dateTime = 'dataTime';
final String pending = 'isPending';
final String color = 'gradientColorIndex';

class AlarmHelper{
  static late  Database _database;
  static late AlarmHelper _alarmHelper;

  AlarmHelper._createInstance();
   factory AlarmHelper() {
    if (_alarmHelper == null){
      _alarmHelper = AlarmHelper._createInstance();
    }
    return _alarmHelper;
  }

  Future<Database> get database async{
    if (_database == null){
      _database = await initializeDatabase();
    }
    return _database;
  }
  Future<Database> initializeDatabase() async{
    var dir = await getDatabasesPath();
    var path  = dir + "alarm.db";


    var database  = await openDatabase(path, version:  1, onCreate: (db, version){
      db.execute('''
      create table $tableName(
        $id integer primary key autoincrement,
        $title text not null,
        $dateTime text not null,
        $pending integer,
        $color integer
      )
      ''');
    }
    );

    return database;
  }


  void insetAlarm(AlarmInfo alarmInfo) async{
     var db = await this.database;
     var result  = await db.insert(tableName, alarmInfo.toMap());
     print(result);
  }

}

真诚感谢任何帮助,提前致谢:)

你知道 late 关键字的作用吗? dart 中的 late 关键字表示:

Don't worry dart, by the time constructor is done running, this variable will have a value

显然,在您的代码中情况并非如此,您的构造函数 AlarmHelper._createInstance() 从未将值分配给 _database_alarmHelper,因此您会遇到延迟初始化错误。

您的代码的某些部分也有 _database == null,这永远不会是真的,因为 _database 如果它为 null 会抛出错误,解决这个问题的方法很简单通过在它们的类型后添加 ? 使 _database_alarmHelper 都可以为 null,所以不要这样:

static late  Database _database;
static late AlarmHelper _alarmHelper;

这个:

static Database? _database;
static AlarmHelper? _alarmHelper;

这样您就不必为它们赋值,因为它们默认为空