ОБНОВЛЕНИЕ (15 июля 2020 г.)
Ответ mFeinstein на данный момент является единственным ответом, который дает мне первое приемлемое решение.
ВОПРОС
Я должен спросить вас, как лучше всего делать то, что я пытаюсь сделать:
- Вызов веб-сервиса в асинхронном режиме
- Разбор ответа
- Выполнение массовых операций с базой данных
Все это без зависания анимации прогресса, например, неопределенного индикатора выполнения.
С первым и вторым пунктом проблем нет. Проблема возникает на третьем этапе, когда происходит массивная вставка базы данных. И я еще не понимаю, как правильно реализовать этот материал.
Какой-то псевдокод для уточнения
Интерфейс (отображается диалоговое окно и отображается индикатор выполнения...)
void callWS() async {
MyProgressDialog _dialog = DialogHelper.showMyProgressDialog(_context, "Data", "Loading...");
await getDataFromService();
_dialog.close();
}
СОЕДИНЕНИЕ (индикатор выполнения не зависает)
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);
}
}
БАЗА ДАННЫХ (индикатор выполнения зависает)
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);
});
}
НЕ РАБОТАЕТ АЛЬТЕРНАТИВА
Я тоже видел подход к функции вычисления, но кажется, что есть проблема в sqflite package
, когда я вызываю операцию БД. Например:
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)'
А также при явном вызове WidgetsFlutterBinding.ensureInitialized()
как первого в runApp(), как это предлагается в журнале ошибок, ничего не происходит.