我们正在开发一个带有 SQLite 数据库的 Flutter APP。我们的要求是在数据库创建时/表初始化后自动插入元数据记录。 元数据在应用程序生命周期中仅应自动插入一次。 我们没有查询格式的这些记录,但它们将从 JSON 文件中读取并插入到 SQLite 数据库表中。
为了实现这个功能,我们在表初始化之后的 initDb() 末尾添加了方法调用,但是表初始化并没有发生。 当我们加载几个页面时, getSetting( ) 就会开始无限循环。 每隔几秒, getSetting() 就会被调用,但不会创建表,也不会插入记录。
即使添加了Try catch,也没有发现错误日志。有趣的是,下面的代码在循环中执行并且不会向前移动。设置模型?设置 = 等待 getSetting("metaDataLoaded");
通过按钮触发时,insertInitialMetaData() 可以完美工作。
有人可以给我一些关于从哪里触发 insertInitialMetaData () 的指导以及当前实现的问题是什么? 另请建议解决此问题的正确方法。(
注意:元数据是执行应用程序逻辑所需的数据,它不能由用户或任何事件(如按钮单击)添加。
下面是我们的DbHelper.dart代码
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DbHelper {
static Database? _db;
Future<Database> get db async {
if (_db != null) {
return _db!;
}
_db = await initDb();
return _db!;
}
Future<Database> initDb() async {
final path = join(await getDatabasesPath(), DB_Name);
return await openDatabase(
path,
version: Version,
onCreate: (db, version) async {
try {
//Create other tables
// Create AppSetting table
db.execute(
'''
CREATE TABLE $Table_AppSettings (
$C_settingId INTEGER PRIMARY KEY AUTOINCREMENT,
$C_key TEXT,
$C_value TEXT,
$C_profile TEXT,
$C_isActive INTEGER NOT NULL DEFAULT 1 ,
$C_createdDate TEXT
)
''',
);
try { // check if the settings metadata preent in the DB
SettingModel? setting = await getSetting("metaDataLoaded");
print('Setting response received.');
if (setting != null) {
//metadata is already exist
print('Setting found: ${setting.key} - ${setting.value}');
} else { // metadata not present
print('Initializing metadata..');
** _handleInsertInitialMetaData(); //method to insert metadata records
** }
}catch (ex) {
print('Error while pulling Settings : $ex');
}
} catch (e) {
print('Error creating tables: $e');
}
},
);
}
//return only the required setting
Future<SettingModel?> getSetting(String key) async {
try{
final dbClient = await db;
final List<Map<String, dynamic>> result = await dbClient.query(
Table_AppSettings,
where: 'isActive = ? AND key = ? AND isActive IS NOT NULL',
whereArgs: [1,key]);
return result.isNotEmpty ? SettingModel.fromMap(result.first) : null;
}catch(e){
print("Error while Getting metadata setting : $e");
rethrow;
}
}
void _handleInsertInitialMetaData() async {
final dbClient = await db;
await insertInitialMetaData(dbClient);
}
Future<void> insertInitialMetaData(Database db) async {
print("Initializing the metaData loading from Json file ..");
try {
//Read JSON data from settings file
String settingsMetaFilePath =
'assets/metadataFiles/settings_initialization.json';
String settingsMetaJsonString =
await rootBundle.loadString(settingsMetaFilePath);
print("Load : settingsMetaJsonString");
var settingsJsonList = json.decode(settingsMetaJsonString) as List<dynamic>;
int j = 0;
// Iterate through the JSON list and insert each setting into the settings table
for (var jsonData in settingsJsonList) {
await saveSettingData(SettingModel.fromJson(jsonData));
}
print("Settings records saved.");
} catch (e) {
print("Error while initialization of data from JSON: $e");
rethrow;
}
}
Future<void> closeDb() async {
if (_db != null) {
await _db!.close();
_db = null;
}
}
}
I/flutter (12688):获取元数据设置 I/chatty (12688): uid=10125(com.example.app) 1.ui 相同 285 行 I/flutter (12688):获取元数据设置 I/flutter (12688):获取元数据设置 I/chatty (12688): uid=10125(com.example.app) 1.ui 相同 69 行 I/flutter (12688):获取元数据设置 I/flutter (12688):获取元数据设置 I/chatty (12688): uid=10125(com.example.app) 1.ui 相同 579 行 I/flutter (12688):获取元数据设置 I/mple.sheti_nex(12688):后台并发复制GC释放了36008(2196KB)个AllocSpace对象,0(0B)个LOS对象,49%空闲,2342KB/4685KB,暂停5.076ms总共72.742ms
I/flutter (12688):获取元数据设置
I/chatty (12688): uid=10125(com.example.app) 1.ui 相同 363 行 I/flutter (12688):获取元数据设置
I/mple.sheti_nex(12688): IncrementDisableThreadFlip 阻塞 6.051 毫秒
I/mple.sheti_nex(12688):后台并发复制GC释放了41559(2492KB)个AllocSpace对象,0(0B)个LOS对象,49%空闲,2243KB/4487KB,暂停5.402ms总共35.193ms
I/flutter (12688):获取元数据设置
我在堆栈页面上找到了相关答案,我按照步骤操作并解决了问题。 主要问题是 - 在创建数据库时,我们试图使用尚未实际完成创建的数据库对象。