sqlite - 插入sqlite颤振而不冻结界面
问题描述
我正在尝试使用颤振在 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,我也尝试了计算,但我无法通过类 db 或类批处理。我不清楚如何在另一个线程中执行这个过程,或者(因为我不能使用隔离)在不阻塞我的 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 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);
}
参考:
非重要参考:
推荐阅读
- c++ - 为什么 std::enable_shared_from_this 允许多个 std::shared_ptr 实例?
- excel - 在单元格公式中引用公共常量
- r - 如何在 Rcpp 中连接列表
- sql - 从 ANSI SQL 中的其他三个列创建具有唯一整数的新列
- python - 如何为孩子的反应获取 own_reactions?以评论点赞为例
- c# - 我如何处理可能成为策略模式解决方案候选的两种情况?
- uwp - 为什么单击时我的 ListViewItem 动画卡住了?
- php - 使用 access_control 管理 security.yml 中的路由
- javascript - 如何检查快速侦听回调中的错误?
- python - 使用来自不同 csv 文件的数据在 csv 文件中创建新列