I would like to use the database in the background thread.
I implemented it using the Isolates doc. It works good on Android but in iOS I receive the following error:
Unsupported operation: Isolate.resolvePackageUri ...
#0 Isolate.resolvePackageUri (dart:isolate-patch/isolate_patch.dart:350:7)
#1 Isolate.spawn (dart:isolate-patch/isolate_patch.dart:388:32)
#2 MoorIsolate.spawn (package:moor/src/runtime/isolate/moor_isolate.dart:75:19)
#3 workManagerCallbackDispatcher.<anonymous closure> (package:ubitime/main_isolated.dart:59:41)
#4 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
#5 _rootRunUnary (dart:async/zone.dart:1134:38)
#6 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#7 _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#8 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#9 Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#10 Future._completeWithValue (dart:async/future_impl.dart:524:5)
#11 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
#12 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
#13 initLog (package:ubitime/main.dart)
#14 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
#15 _rootRunUnary (dart:async/zone.dart:1134:38)
#16 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#17 _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#18 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#19 Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#20 Future._completeWithValue (dart:async/future_impl.dart:524:5)
#21 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
#22 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
#23 getApplicationSupportDirectory (package:path_provider/path_provider.dart)
#24 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
#25 _rootRunUnary (dart:async/zone.dart:1134:38)
#26 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#27 _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#28 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#29 Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#30 Future._completeWithValue (dart:async/future_impl.dart:524:5)
#31 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
#32 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
#33 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart)
#34 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
#35 _rootRunUnary (dart:async/zone.dart:1134:38)
#36 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
#37 _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
#38 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
#39 Future._propagateToListeners (dart:async/future_impl.dart:709:32)
#40 Future._completeWithValue (dart:async/future_impl.dart:524:5)
#41 Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:554:7)
#42 _rootRun (dart:async/zone.dart:1126:13)
#43 _CustomZone.run (dart:async/zone.dart:1023:19)
#44 _CustomZone.runGuarded (dart:async/zone.dart:925:7)
#45 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23)
#46 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
#47 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
Maybe the problem is related to this issue and it has nothing to do with Moor but I would like to hear your opinion as well.
Please also note that I use WorkManager and I simulated the background fetch from Xcode.
flutter --version
Flutter 1.12.13+hotfix.8 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 0b8abb4724 (3 weeks ago) • 2020-02-11 11:44:36 -0800
Engine • revision e1e6ced81d
Tools • Dart 2.7.0
dependencies:
moor: ^2.4.1
moor_ffi: ^0.4.0
dev_dependencies:
moor_generator: ^2.4.0
Did you see such problems on iOS side or did I miss something?
Thank you in advance.
There is nothing in moor that calls Isolate.resolvePackageUri, we just call Isolate.spawn. I would expect that to work in all cases, so I'm inclined to call this a Flutter bug.
If you use something like Flutter's compute function from the background, does that work? If it does, I can take a look at what moor might be doing differently. If it doesn't, it's definitely a Flutter bug...
Thank you for your reply.
It turned out that this has nothing to do with Moor. We are already in a background isolate when WorkManager's callbackDispatcher is called. Fortunately we have access also to getApplicationDocumentsDirectory so the database can be initialised like in the main isolate.
I will add some code. Maybe it will be useful for someone who wants to try Moor with WorkManager.
Moor initialisation like suggested on the Getting Started page.
@UseMoor(
tables: [...],
daos: [...])
class Database extends _$Database {
Database() : super(_openConnection());
@override
int get schemaVersion => 1;
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(join(dbFolder.path, Const.databaseName));
return VmDatabase(file);
});
}
The callbackDispatcher of WorkManager.
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) async {
var database = Database();
/// You can use the database here normally.
bool success = true;
return Future.value(success);
});
}
Thank you again.
Most helpful comment
Thank you for your reply.
It turned out that this has nothing to do with Moor. We are already in a background isolate when WorkManager's
callbackDispatcheris called. Fortunately we have access also togetApplicationDocumentsDirectoryso the database can be initialised like in the main isolate.I will add some code. Maybe it will be useful for someone who wants to try Moor with WorkManager.
Moor initialisation like suggested on the Getting Started page.
The
callbackDispatcherof WorkManager.Thank you again.