插入sqlite颤振,而不冻结接口

插入sqlite颤振,而不冻结接口,sqlite,flutter,dart,sqflite,Sqlite,Flutter,Dart,Sqflite,我正在尝试使用flatter在sqlite内存数据库中插入很多行(大约12k或更多) 我从API中获取数据,并使用计算函数来处理Json中的数据。 现在我需要将这些数据添加到内存中的数据库中,为此,我使用一个批处理事务 batchInsertEventSong(列表行)异步{ Database db=wait instance.Database; 事务((txn)异步{ Batch Batch=txn.Batch(); for(按行排列){ 地图行={ DatabaseHelper.column

我正在尝试使用flatter在sqlite内存数据库中插入很多行(大约12k或更多)

我从API中获取数据,并使用计算函数来处理Json中的数据。 现在我需要将这些数据添加到内存中的数据库中,为此,我使用一个批处理事务

batchInsertEventSong(列表行)异步{
Database db=wait instance.Database;
事务((txn)异步{
Batch Batch=txn.Batch();
for(按行排列){
地图行={
DatabaseHelper.columnIdSong:song.id,
DatabaseHelper.columnTitle:song.title,
DatabaseHelper.ColumnTranslator:song.Translator
};
批.插入(表,行);
}
batch.commit();
}
}
但是这个函数在插入过程中阻塞了我的UI,我也尝试了compute,但是我无法传递类db或类批处理。 我不清楚如何在另一个线程中执行这个过程,或者(因为我不能使用隔离)在不阻塞UI的情况下执行

有什么建议吗?

更新2020-05-15 这将不起作用,请参见:

注:末尾提供完整代码

步骤1:使您的方法静态并使其无效
static batchInsertEventSong(列出行){
Database db=wait instance.Database;
事务((txn)异步{
Batch Batch=txn.Batch();
for(按行排列){
地图行={
DatabaseHelper.columnIdSong:song.id,
DatabaseHelper.columnTitle:song.title,
DatabaseHelper.ColumnTranslator:song.Translator
};
批.插入(表,行);
}
batch.commit();
}
}
步骤2:创建新方法(通常但不是必需的)为相同的名称添加Async
Future batchInsertEventSongAsync(列出行){
}
第3步:使用static方法调用compute并返回
返回计算(batchInsertEventSong,行);

步骤[1,2,3]代码审查
Future batchInsertEventSongAsync(列出行){
返回计算(_batchInsertEventSong,行);
}
静态_batchInsertEventSong(列表行){
Database db=wait instance.Database;
事务((txn)异步{
Batch Batch=txn.Batch();
for(按行排列){
地图行={
DatabaseHelper.columnIdSong:song.id,
DatabaseHelper.columnTitle:song.title,
DatabaseHelper.ColumnTranslator:song.Translator
};
批.插入(表,行);
}
batch.commit();
}
}

完整代码
导入'dart:async';
进口“包装:颤振/基础.dart”;
进口“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:Scaffold(正文:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
FlatButton.icon(
图标:图标(图标。备份),
标签:文本(“长期经营”),
onPressed:()异步{
var rows=await RsetApi.getRawsAsync();
等待数据库。\u saveRaws(行);
},
),
FlatButton.icon(
图标:图标(图标。备份),
标签:文本(“短操作”),
已按下:(){
Scaffold.of(context.hideCurrentSnackBar();
Scaffold.of(上下文).showSnackBar(新的SnackBar(
内容:新文本(DateTime.now().toIso8601String()),
));
},
),
],
),
),
);
}
}
类RsetApi{
静态未来getRawsAsync(){
返回compute(_getRaws,null);
}
静态列表(pram1){
var rows=List();
对于(变量i=1;i<12000;i++){
添加(EventSong(i));
打印(“获取图纸”+(i/12000.toString());
}
返回行;
}
}
类数据库{
静态未来saveRawsAsync(列表行){
返回计算(_saveRaws,rows);
}
静态保存(列表行){
对于(变量i=1;i
裁判:
非重要参考:

对不起,我忘了说,比如说12K左右的时间大约需要2秒,提交大约需要4秒。如果将“添加到”
batch
放在较小的块中,你是什么意思?执行
batch.commit();
不是在最后,而是在一些循环之后?我尝试添加
如果(I%1000==0)batch.commit(noResult:true)
因此它每1000个项目提交一行,并在循环结束时提交。但这会让我的UI阻塞12秒左右……在flift中是否有睡眠或处理事件(如在Qt中)来让主线程执行一点空气?我认为PlatformChannels(
sqflite
insert
)不适用于隔离(
compute
)。这个例子有用吗?@Martyns你有没有关于这个事实的参考资料(url),所以我可以稍后检查。GH有几个问题,这是@Mo的主要问题