在不冻结界面的情况下插入sqlite flutter
Insert sqlite flutter without freezing the interface
我正在尝试使用 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,我也尝试了计算,但我无法传递 class 数据库或 class 批处理。
我不清楚如何在另一个线程中执行此过程或(因为我不能使用隔离)执行而不阻塞我的 UI.
有什么建议吗?
更新 2020 - 05 - 15
这行不通见:
注意:完整代码在文末提供
第 1 步:使您的方法静态化并使其无效
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();
}
}
第 2 步:创建新方法(通常但不需要为同名添加 Async)
Future batchInsertEventSongAsync(List<EventSong> rows) {
}
第 3 步:使用静态方法和 return
调用计算
return compute(batchInsertEventSong, rows);
步骤 [1,2,3] 代码审查
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);
}
参考:
non-important 参考:
我正在尝试使用 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,我也尝试了计算,但我无法传递 class 数据库或 class 批处理。 我不清楚如何在另一个线程中执行此过程或(因为我不能使用隔离)执行而不阻塞我的 UI.
有什么建议吗?
更新 2020 - 05 - 15
这行不通见:
注意:完整代码在文末提供
第 1 步:使您的方法静态化并使其无效
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();
}
}
第 2 步:创建新方法(通常但不需要为同名添加 Async)
Future batchInsertEventSongAsync(List<EventSong> rows) {
}
第 3 步:使用静态方法和 return
调用计算 return compute(batchInsertEventSong, rows);
步骤 [1,2,3] 代码审查
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);
}