UPDATE (15 july 2020)
mFeinstein's response, for now, is the only answer which gives me the first acceptable solution.
QUESTION
I have to ask you what is the best approach for doing what i'm trying to do:
- Calling a web service in async mode
- Parsing response
- Performing massive database operations
All of this without freezing progress animation, like indeterminate progress bar.
There isn't problem at first and second point. Problem occurs at third, when a massive database insert is in act. And i don't understand yet how is the right way for implementing this stuff.
Some pseudo piece of code for clarify
UI (Dialog is shown and progress bar runs...)
void callWS() async {
MyProgressDialog _dialog = DialogHelper.showMyProgressDialog(_context, "Data", "Loading...");
await getDataFromService();
_dialog.close();
}
CONNECTION (Freeze doesn't occur on progress bar)
static Future<void> getDataFromService() async {
String uri = MY_URI;
String wsMethod = MY_WS_METHOD;
String wsContract = MY_WS_CONTRACT;
SoapObject myRequest = SoapObject.fromSoapObject(namespace: my_namespace, name: wsMethod);
MyConnectionResult response = await _openMyConnection(myRequest, uri, wsContract, wsMethod);
if (response.result == MyResultEnum.OK) {
await _parseResponse(response.data);
}
}
DATABASE (Freeze occurs on progress bar)
static Future<void> _parseResponse(xml.XmlElement elements) async {
Database db = await MyDatabaseHelper.openConnection();
db.transaction((tx) async {
Batch batch = tx.batch();
for (xml.XmlElement oi in elements.children) {
int id = int.parse(oi.findElements("ID").first.text);
String name = oi.findElements("NAME").first.text;
DatabaseHelper.insertElement(
tx,
id: id,
name: name,
);
}
batch.commit(noResult: true);
});
}
NOT WORKING ALTERNATIVE
I saw "compute" function approach too, but it seems there is a problem in sqflite package
, when i call a db operation. For example:
static Future<void> performDelete() async {
Database db = await openMyConnection();
compute(_performDeleteCompute, db);
}
static void _performDeleteCompute(Database db) async {
db.rawQuery("DELETE MYTABLE");
}
Console error:'
-> Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
-> If you are running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization),
then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first.
-> error defaultBinaryMessenger.<anonymous closure> (package:flutter/src/services/binary_messenger.dart:76:7)
#1 defaultBinaryMessenger (package:flutter/src/services/binary_messenger.dart:89:4)
#2 MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:140:62)
#3 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:146:35)
#4 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
#5 invokeMethod (package:sqflite/src/sqflite_impl.dart:17:13)
#6 SqfliteDatabaseFactoryImpl.invokeMethod (package:sqflite/src/factory_impl.dart:31:7)
#7 SqfliteDatabaseMixin.invokeMethod (package:sqflite_common/src/database_mixin.dart:287:15)
#8 SqfliteDatabaseMixin.safeInvokeMethod.<anonymous closure> (package:sqflite_common/src/database_mixin.dart:208:43)
#9 wrapDatabaseException (package:sqflite/src/exception_impl.dart:7:32)
#10 SqfliteDatabaseFactoryImpl.wrapDatabaseException (package:sqflite/src/factory_impl.dart:27:7)
#11 SqfliteDatabaseMixin.safeInvokeMethod (package:sqflite_common/src/database_mixin.dart:208:15)
#12 SqfliteDatabaseMixin.txnRawQuery.<anonymous closure> (package:sqflite_common/src/database_mixin.dart:394:36)
#13 SqfliteDatabaseMixin.txnSynchronized.<anonymous closure> (package:sqflite_common/src/database_mixin.dart:327:22)
#14 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:32:26)
#15 SqfliteDatabaseMixin.txnSynchronized (package:sqflite_common/src/database_mixin.dart:323:33)
#16 SqfliteDatabaseMixin.txnRawQuery (package:sqflite_common/src/database_mixin.dart:393:12)
#17 SqfliteDatabaseExecutorMixin._rawQuery (package:sqflite_common/src/database_mixin.dart:126:15)
#18 SqfliteDatabaseExecutorMixin.rawQuery (package:sqflite_common/src/database_mixin.dart:120:12)
#19 DatabaseHelper._performDeleteCompute(package:flutter_infocad/Database/DatabaseHelper.dart:368:8)'
And also explicitly calling the WidgetsFlutterBinding.ensureInitialized()
as first in runApp(), as suggested in the error log, nothing happens.