我正在尝试使用 flutter 在 sqlite 内存数据库中插入大量行(大约 12k 或更多)。
我从 API 获取数据并使用计算函数来处理来自 Json 的数据。 现在我需要将这些数据添加到内存中的数据库中,为此我使用批量事务。
batchInsertEventSong(List<EventSong> rows) async {
Database db = await instance.database;
db.transaction((txn) async {
Batch batch = txn.batch();
for (var song in rows) {
Map<String, dynamic> row = {
DatabaseHelper.columnIdSong: song.id,
DatabaseHelper.columnTitle: song.title,
DatabaseHelper.columnInterpreter: song.interpreter
};
batch.insert(table, row);
}
batch.commit();
}
}
但是这个函数在插入过程中阻塞了我的用户界面,我也尝试使用计算,但我无法传递类数据库或类批处理。 我不清楚如何在另一个线程中执行此进程,或者(因为我无法使用隔离)执行而不阻塞我的 UI。
有什么建议吗?
static batchInsertEventSong(List<EventSong> rows) {
Database db = await instance.database;
db.transaction((txn) async {
Batch batch = txn.batch();
for (var song in rows) {
Map<String, dynamic> row = {
DatabaseHelper.columnIdSong: song.id,
DatabaseHelper.columnTitle: song.title,
DatabaseHelper.columnInterpreter: song.interpreter
};
batch.insert(table, row);
}
batch.commit();
}
}
Future batchInsertEventSongAsync(List<EventSong> rows) {
}
return compute(batchInsertEventSong, rows);
Future batchInsertEventSongAsync(List<EventSong> rows) {
return compute(_batchInsertEventSong, rows);
}
static _batchInsertEventSong(List<EventSong> rows) {
Database db = await instance.database;
db.transaction((txn) async {
Batch batch = txn.batch();
for (var song in rows) {
Map<String, dynamic> row = {
DatabaseHelper.columnIdSong: song.id,
DatabaseHelper.columnTitle: song.title,
DatabaseHelper.columnInterpreter: song.interpreter
};
batch.insert(table, row);
}
batch.commit();
}
}
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: MyHomePage(title: 'Flutter Demo Home Page')),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
icon: Icon(Icons.backup),
label: Text("Long Opreation"),
onPressed: () async {
var rows = await RsetApi.getRawsAsync();
await Database._saveRaws(rows);
},
),
FlatButton.icon(
icon: Icon(Icons.backup),
label: Text("Short Opreation"),
onPressed: () {
Scaffold.of(context).hideCurrentSnackBar();
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text(DateTime.now().toIso8601String()),
));
},
),
],
),
),
);
}
}
class RsetApi {
static Future<List<EventSong>> getRawsAsync() {
return compute(_getRaws, null);
}
static List<EventSong> _getRaws(pram1) {
var rows = List<EventSong>();
for (var i = 1; i < 12000; i++) {
rows.add(EventSong(i));
print("fetching raws " + (i / 12000).toString());
}
return rows;
}
}
class Database {
static Future saveRawsAsync(List<EventSong> rows) {
return compute(_saveRaws, rows);
}
static _saveRaws(List<EventSong> rows) {
for (var i = 1; i < rows.length; i++) {
print("saving raws " + (i / rows.length).toString());
}
}
}
class EventSong {
int id;
EventSong(this.id);
}