인프런 커뮤니티 질문&답변
플러터 프로그래밍 _openConnection 오류
해결된 질문
작성
·
132
0
오류한줄이 해결이 안되서 문의드립니다. 코드팩토리의 플러터프로그래밍 2판 18장입니다.
database폴더안의 drift_database.dart에서 _openConnection()부분이 오류로 뜹니다.
해당 내용은 The instance member '_openConnection' can't be accessed in an initializer. 입니다
main.dart
import 'package:calendar_scheduler2/screen/home_screen.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:calendar_scheduler2/database/drift_database.dart';
import 'package:get_it/get_it.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeDateFormatting();
final database = LocalDatabase();
GetIt.I.registerSingleton<LocalDatabase>(database);
runApp(
MaterialApp(
home: HomeScreen(),
),
);
}schedule_bottom_sheet.dart
import 'package:calendar_scheduler2/component/custom_text_field.dart';
import 'package:calendar_scheduler2/const/colors.dart';
import 'package:flutter/material.dart';
import 'package:drift/drift.dart' hide Column;
import 'package:get_it/get_it.dart';
import 'package:calendar_scheduler2/database/drift_database.dart';
class ScheduleBottomSheet extends StatefulWidget {
final DateTime selectedDate;
const ScheduleBottomSheet({
required this.selectedDate,Key? key}) : super(key: key);
@override
State<ScheduleBottomSheet> createState() => _ScheduleBottomSheetState();
}
class _ScheduleBottomSheetState extends State<ScheduleBottomSheet> {
final GlobalKey<FormState> formKey = GlobalKey();
int? startTime;
int? endTime;
String? content;
@override
Widget build(BuildContext context) {
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
return Form(
key: formKey,
child: SafeArea(
child: Container(
height: MediaQuery.of(context).size.height / 2 + bottomInset,
color: Colors.white,
child: Padding(
padding: EdgeInsets.only(
left: 8, right: 8, top: 8, bottom: bottomInset),
child: Column(
children: [
Row(
children: [
Expanded(
child: CustomTextField(
label: '시작 시간',
isTime: true,
onSaved: (String? val) {
startTime = int.parse(val!);
},
validator: timeValidator,
),
),
const SizedBox(width: 16.0),
Expanded(
child: CustomTextField(
label: '종료 시간',
isTime: true,
onSaved: (String? val) {
endTime = int.parse(val!);
},
validator: timeValidator,
),
),
],
),
SizedBox(height: 8.0),
Expanded(
child: CustomTextField(
label: '내용',
isTime: false,
onSaved: (String? val) {
content = val;
},
validator: contentValidator,
),
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: onSavePressed,
style: ElevatedButton.styleFrom(
backgroundColor: PRIMARY_COLOR,
),
child: Text('저장'),
),
),
],
),
),
),
),
);
}
void onSavePressed() async {
if (formKey.currentState!.validate()){
formKey.currentState!.save();
await GetIt.I<LocalDatabase>().createSchedule(
SchedulesCompanion(
startTime: Value(startTime!),
endTime: Value(endTime!),
content: Value(content!),
date: Value(widget.selectedDate),
),
);
Navigator.of(context).pop();
}
}
String? timeValidator(String? val) {
if (val == null) {
return '값을 입력해주세요';
}
int? number;
try {
number = int.parse(val);
} catch (e) {
return '숫자를 입력해주세요';
}
if (number < 0 || number > 24) {
return '0시부터 24시 사이를 입력해주세요';
}
return null;
}
String? contentValidator(String? val) {
if (val == null || val.length == 0) {
return '값을 입력해주세요';
}
return null;
}
}drift_database.dart
import 'package:calendar_scheduler2/model/schedule.dart';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'dart:io';
part 'drift_database.g.dart';
@DriftDatabase(
tables: [
Schedules,
],
)
class LocalDatabase extends _$LocalDatabase {
LocalDatabase() : super(_openConnection());
Stream<List<Schedule>> watchSchedules(DateTime date) =>
(select(schedules)
..where((tbl) => tbl.date.equals(date))).watch();
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return NativeDatabase(file);
});
}
Future<int> createSchedule(SchedulesCompanion data) =>
into(schedules).insert(data);
Future<int> removeSchedule(int id) =>
(delete(schedules)
..where((tbl) => tbl.id.equals(id))).go();
@override
int get schemaVersion => 1;
}
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
dhgpfla0613님의 질문에 대한 답변입니다. Flutter에서 제시한 오류 메시지 “The instance member ‘_openConnection’ can’t be accessed in an initializer”는 인스턴스 멤버 ‘_openConnection’이 초기화자에서 접근될 수 없다는 것을 의미합니다. 이 문제는 LocalDatabase 클래스의 생성자에서 _openConnection 메서드를 직접 호출하여 발생합니다. Dart에서는 생성자에서 다른 인스턴스 메서드를 직접 호출할 수 없습니다. 대신 이 문제를 해결할 수 있는 한 가지 방법은 _openConnection 메서드를 static으로 만드는 것입니다.
수정된 drift_database.dart 파일의 LocalDatabase 클래스 부분:
class LocalDatabase extends _$LocalDatabase {
LocalDatabase() : super(_openConnection());
static LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
return NativeDatabase(file);
});
}
// 기존 코드를 여기에 포함합니다.
}
위와 같이 _openConnection 메서드를 static으로 변경함으로써 클래스 생성자에서 이 메서드를 직접 호출할 수 있게 됩니다. 이 방법은 _openConnection 메서드가 외부 인스턴스 변수나 메서드에 의존하지 않을 때 유효합니다. 게시한 코드에 따르면 _openConnection 메서드는 외부 상태에 의존하지 않으므로 이 변경이 가능하고 문제를 해결해야 합니다.




