#android #sql #flutter #dart #flutter-moor
#Android #sql #флаттер #dart #flutter-moor
Вопрос:
Всякий раз, когда я добавляю новую строку в свою базу данных в своем приложении flutter, я получаю эту ошибку :
ПРЕДУПРЕЖДЕНИЕ (moor): похоже, что вы создали classAppDatabase базы данных несколько раз. Когда эти две базы данных используют один и тот же QueryExecutor, возникают условия гонки, которые могут повредить базу данных.
Я прочитал разные статьи и пришел к выводу, что, возможно, я вызывал конструктор более одного раза, но все еще не нашел выхода из этого.
Вот несколько фрагментов кода для начальной ссылки:
pubspec.yaml:
dependencies:
flutter:
sdk: flutter
basic_utils: ^2.6.3
cupertino_icons: ^1.0.0
flutter_blue: ^0.7.3
google_fonts: ^1.1.1
http: ^0.12.2
json_annotation: ^3.1.1
logging: ^0.11.4
#moor: ^3.4.0
moor_flutter: ^3.1.0
provider: ^4.3.3
sqflite: ^1.3.2 3
sqlite3_flutter_libs: ^0.3.0
url_launcher: ^5.7.10
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.9.0
chopper_generator: ^3.0.4
json_serializable: ^3.3.0
moor_generator: ^3.4.1
moor_database.dart:
import 'package:moor_flutter/moor_flutter.dart';
part 'moor_database.g.dart';
@DataClassName('AvailableFunctionTable') //Final Table Name
class AvailableFunctionsTable extends Table {
IntColumn get id => integer()();
TextColumn get make => text().withLength(min: 1, max: 50)();
TextColumn get model => text().withLength(min: 1, max: 50).nullable()();
IntColumn get year => integer().nullable()();
TextColumn get functionType => text().withLength(min: 1, max: 100)();
TextColumn get functionName => text().withLength(min: 1, max: 100)();
@override
Set<Column> get primaryKey => {id};
}
@UseMoor(tables: [AvailableFunctionsTable])
class AppDatabase extends _$AppDatabase {
AppDatabase()
: super(FlutterQueryExecutor.inDatabaseFolder(
path: "db.sqlite", logStatements: true));
int get schemaVersion => 1;
Future<List<AvailableFunctionTable>> getAllAvailableFunctionss() =>
select(availableFunctionsTable).get();
Stream<List<AvailableFunctionTable>> watchAllAvailableFunctionss() =>
select(availableFunctionsTable).watch();
Future insertAvailableFunctions(AvailableFunctionTable availableFunctions) =>
into(availableFunctionsTable).insert(availableFunctions);
Future updateAvailableFunctions(AvailableFunctionTable availableFunctions) =>
update(availableFunctionsTable).replace(availableFunctions);
Future deleteAvailableFunctions(AvailableFunctionTable availableFunctions) =>
delete(availableFunctionsTable).delete(availableFunctions);
}
main.dart:
void main() {
runApp(AvFunctionsScreen());
}
class AvFunctionsScreen extends StatefulWidget {
@override
_AvFunctionsScreenState createState() => _AvFunctionsScreenState();
}
class _AvFunctionsScreenState extends State<AvFunctionsScreen> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text("AvFunctionsScreen List"),
),
body: SingleChildScrollView(child: NewEntry()),
),
);
}
}
class NewEntry extends StatefulWidget {
@override
_NewEntryState createState() => _NewEntryState();
}
class _NewEntryState extends State<NewEntry> {
TextEditingController idController = TextEditingController();
TextEditingController makeController = TextEditingController();
TextEditingController modelController = TextEditingController();
TextEditingController functionNameController = TextEditingController();
TextEditingController functionTypeController = TextEditingController();
TextEditingController yearController = TextEditingController();
bool isloading = false;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'id'),
keyboardType: TextInputType.number,
controller: idController,
),
TextField(
decoration: InputDecoration(hintText: 'make'),
keyboardType: TextInputType.text,
controller: makeController,
),
TextField(
decoration: InputDecoration(hintText: 'model'),
keyboardType: TextInputType.text,
controller: modelController,
),
TextField(
decoration: InputDecoration(hintText: 'year'),
keyboardType: TextInputType.number,
controller: yearController,
),
TextField(
decoration: InputDecoration(hintText: 'func type'),
keyboardType: TextInputType.text,
controller: functionTypeController,
),
TextField(
decoration: InputDecoration(hintText: 'func name'),
keyboardType: TextInputType.text,
controller: functionNameController,
),
RaisedButton(
onPressed: () {
setState(() {
AppDatabase().insertAvailableFunctions(AvailableFunctionTable(
id: int.parse(idController.text),
make: makeController.text,
model: modelController.text,
year: int.parse(yearController.text),
functionName: functionNameController.text,
functionType: functionTypeController.text,
));
idController.clear();
makeController.clear();
modelController.clear();
yearController.clear();
functionNameController.clear();
functionTypeController.clear();
});
},
color: Colors.green,
child: Text("Add info"),
),
Container(
height: 700,
width: double.infinity,
child: StreamBuilder(
stream: AppDatabase().watchAllAvailableFunctionss(),
builder: (context,
AsyncSnapshot<List<AvailableFunctionTable>> snapshot) {
return ListView.builder(
itemBuilder: (_, index) {
return Card(
color: Colors.blueAccent,
child: ListTile(
leading: CircleAvatar(
child: Text('${index 1}'),
radius: 20,
),
title: Text(snapshot.data[index].id.toString()
' '
snapshot.data[index].year.toString()),
subtitle: Text(snapshot.data[index].make
' '
snapshot.data[index].model
' '
snapshot.data[index].functionType
' '
snapshot.data[index].functionName),
trailing: IconButton(
icon: Icon(Icons.delete_outline),
onPressed: () {
setState(() {
AppDatabase().deleteAvailableFunctions(
snapshot.data[index]);
});
},
color: Colors.red,
)),
);
},
itemCount: snapshot?.data?.length,
);
},
),
)
],
);
}
}
Хотя я получаю свой вывод нормально, и приложение, похоже, работает, оно выдает мне ошибку в консоли отладки каждый раз при горячем перезапуске :
Метод ‘[]’ был вызван в null. Получатель: null Попытался вызвать: » (Фактическая ошибка содержит пару квадратных скобок, за которыми следует пара круглых скобок с нулем между круглыми скобками вместо кавычек)
Итак, я хочу избавиться от обеих этих ошибок, чтобы я мог начать интеграцию своих API
Заранее спасибо!
Ответ №1:
Вы не должны вызывать AppDatabase()
более одного раза в своем приложении. AppDatabase()
Каждый раз при вызове создается новый экземпляр, и в итоге получается много экземпляров базы данных. Лучший способ сделать это — создать его один раз и предоставить его необходимым компонентам. Кроме того, проверьте шаблон Singleton в Dart.