Comments (20)
That will be WidgetsFlutterBinding.ensureInitialized();
instead of FlutterWidgetsBinding.ensureInitialized()
right :D
from sqlite3.dart.
What the hell is Android doing here? 😧 But it's interesting to know that the object gets put there...
applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
function threw an error. (Null check operator used on a null value
).
Are you using the function before runApp
by any chance? It sounds like a missed initialization on the Flutter method channel, are you calling FlutterWidgetsBinding.ensureInitialized()
? But even then it's weird that this only fails on some devices... Do you have a stack trace by any chance?
from sqlite3.dart.
I'm not sure... 🙈
Before we do anything, we do WidgetsFlutterBinding.ensureInitialized();
, so the function is called after this, but before the runApp()
(inside a preResolve
).
@singleton
@preResolve
Future<DatabaseConnection> provideDatabaseConnection(...) async {
...
await Isolate.spawn(
_startBackground, <--- This function calls the applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
...
);
The stacktrace is
E/flutter (10337): [ERROR:flutter/runtime/dart_isolate.cc(1137)] Unhandled exception:
E/flutter (10337): Null check operator used on a null value
E/flutter (10337): #0 MethodChannel.binaryMessenger package:flutter/…/services/platform_channel.dart:142
E/flutter (10337): #1 MethodChannel._invokeMethod package:flutter/…/services/platform_channel.dart:148
E/flutter (10337): #2 MethodChannel.invokeMethod package:flutter/…/services/platform_channel.dart:331
E/flutter (10337): #3 applyWorkaroundToOpenSqlCipherOnOldAndroidVersions package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart:34
E/flutter (10337): #4 _startBackground package:our_package/di/injectable.dart:156
E/flutter (10337): #5 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:286:17)
E/flutter (10337): #6 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
The reason that this only fails on some devices is that the workaround only calls invokeMethod
when the DynamicLibrary.open('libsqlcipher.so');
fails. And for most devices, opening the file is not an issue.
Future<void> applyWorkaroundToOpenSqlCipherOnOldAndroidVersions() async {
if (!Platform.isAndroid) return;
try {
DynamicLibrary.open('libsqlcipher.so');
} on ArgumentError {
// Ok, the regular approach failed. Try to open sqlite3 in Java, which seems
// to fix the problem.
await _platform.invokeMethod('doesnt_matter');
// Try again. If it still fails we're out of luck.
DynamicLibrary.open('libsqlcipher.so');
}
}
I'll try removing the preresolve next week, but this has quite a few implications in the app and will still result in using a workaround, which I don't really like 🤔 (not that my suggestion is fool-proof 😬)
from sqlite3.dart.
From the stack trace, it looks like you're opening the native library in a new isolate. That's completely fine, but it means that you also need to call FlutterWidgetsBinding.ensureInitialized()
in _startBackground
. Essentially, the binding (and the messenger) need to be initialized on each isolate separately.
If possible, an alternative would be to always open the library in the main isolate (even if it's not used there). Once opened correctly, the default path attempting to open libsqlcipher.so
in a new isolate will work too.
from sqlite3.dart.
I think it has something to do with aab files. I built the apk and installed it with adb. And everything works fine. If I download the app from the playstore. -> AAB -> the database doesn't work.
On a side note. We are also using obfuscation in dart & android. But again that works perfectly when building the aab files.
I am using a Nexus 5 (Phone) & Nexus 7 (Tablet). Both have this issue (reproducable when using the playstore)
from sqlite3.dart.
@simolus3 We do have this in our build.gradle
release {
...
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86_64', 'x86'
}
...
}
Could that result in issues?
from sqlite3.dart.
The abiFilters
should not be a problem (but are you sure that you're actually doing a Flutter release build on 32-bit x86
? That would require some hacks).
App bundles changing the location of the actual library could explain this. Anyway, did you try using applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
with FlutterWidgetsBinding.ensureInitialized()
in the background isolate? AFAIK that should also fix the problem.
from sqlite3.dart.
I am building to the playstore internal test because that is the only place where I can reproduce this issue. The FlutterWidgetsBinding.ensureInitialized()
should be the first thing we do in the _startBackground right? I did not see this in your isolate/encryption guide.
from sqlite3.dart.
Yes, calling ensureInitialized
before applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
is necessary for each isolate. So doing that as a first call in _startBackground
can't hurt :D
I think there were some general issues with using platform channels in background isolates, but AFAIK most of them have been resolved.
from sqlite3.dart.
WidgetsFlutterBinding.ensureInitialized();
does not work. The app get stuck at startup. (When creating the dependency tree, I will try this in debug to get a stacktrace but in release (playstore I do not get a stacktrace)
from sqlite3.dart.
This is the error I got (After deobfuscation)
10-25 17:32:20.629 11211-11300/? E/flutter: [ERROR:flutter/runtime/dart_isolate.cc(1137)] Unhandled exception:
LateInitializationError: Field '_tbc@15065589' has not been initialized.
Warning: This VM has been configured to produce stack traces that violate the Dart standard.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 11211, tid: 11300, name DartWorker
build_id: '4ff9bfa0daa533efd010fb425f5e2abb'
isolate_dso_base: 9f5ae000, vm_dso_base: 9f5ae000
isolate_instructions: 9f5ba000, vm_instructions: 9f5b0000
#0 PlatformDispatcher.initialLifecycleState (dart:ui/platform_dispatcher.dart)
#1 SingletonFlutterWindow.initialLifecycleState (dart:ui/window.dart:399:58)
#2 ServicesBinding.readInitialLifecycleStateFromNativeWindow (package:flutter/src/services/binding.dart:185:71)
#3 ServicesBinding.initInstances (package:flutter/src/services/binding.dart:35:5)
#4 PaintingBinding.initInstances (package:flutter/src/painting/binding.dart:22:11)
#5 SemanticsBinding.initInstances (package:flutter/src/semantics/binding.dart:22:11)
#6 RendererBinding.initInstances (package:flutter/src/rendering/binding.dart:28:11)
#7 WidgetsBinding.initInstances (package:flutter/src/widgets/binding.dart:277:11)
#8 new BindingBase (package:flutter/src/foundation/binding.dart:56:5)
#9 new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
#10 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
#11 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
#12 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
#13 new Completer (dart:async/future.dart)
#14 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart:704:48)
#15 WidgetsFlutterBinding.ensureInitialized (package:flutter/src/widgets/binding.dart)
#16 _startBackground (package:our_app/di/injectable.dart:153:25)
#17 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:286:17)
#18 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
late String _initialLifecycleState;
is still null
from sqlite3.dart.
It has something to do with the aab files. If I build with --split-apk it works perfectly. If I build an aab and upload that one to the playstore it is broken.
from sqlite3.dart.
That's unfortunate. Do you start a main UI isolate before starting the background isolate? If you have a chance to await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
on the main isolate before starting the background isolate, it might work because the loaded libraries are shared across threads.
There's a bit more information on this workaround here: simolus3/drift#895 (comment)
from sqlite3.dart.
I will try that tomorrow. I have been working on this today for more than 9 hours. I couldn't think straight anymore. 🤞🤞🤞
from sqlite3.dart.
The applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
should be called in the _startBackground or before?
from sqlite3.dart.
Try calling it before. So in the main isolate before you do Isolate.spawn(_startBackground)
.
from sqlite3.dart.
If we only call applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
before we start the new isolate it doesn't work.
We now call applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
before the start of the isolate. And in _startBackground be do this:
Future<void> _startBackground(_IsolateStartRequest request) async {
if (Platform.isIOS) {
open.overrideFor(OperatingSystem.iOS, () => DynamicLibrary.process());
} else if (Platform.isAndroid) {
await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions();
open.overrideFor(OperatingSystem.android, openCipherOnAndroid);
}
final executor = VmDatabase(File(request.targetPath), setup: (db) => db.execute("PRAGMA key = '${request.password}'"));
final moorIsolate = MoorIsolate.inCurrent(() => DatabaseConnection.fromExecutor(executor));
request.sendMoorIsolate.send(moorIsolate);
}
Because calling WidgetsFlutterBinding.ensureInitialized();
crashes as well. We don't do that in _startBackground
from sqlite3.dart.
That fixed it and a new release is in the make. Thank you for your support!
from sqlite3.dart.
Yes indeed! Thanks again for your support. We do think that this step should be documented somewhere.
When to call applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
with isolate
And when to call applyWorkaroundToOpenSqlCipherOnOldAndroidVersions
without isolate
from sqlite3.dart.
I have added matching warnings to the readme in f05f5d6.
from sqlite3.dart.
Related Issues (20)
- how to insert blob data HOT 1
- request: support sqlite3_flutter_libs `json_extract` HOT 1
- Compiler Error In iOS HOT 10
- Database disk image is malformed, HOT 7
- [Docs] Add Docs, stating `BLOB` type, expects `Uint8List`, not `T` or `Object`
- `Database.lastInsertRowId` should `return` `int?`, instead of `int` HOT 1
- how to get table-count of db, through `SQLite3.exec("SELECT count(*) FROM sqlite_schema WHERE type = 'table'").getInt()` HOT 1
- Implement a `pkg:realm:Realm:write` like method to `Database`, which calls the passed function in a transaction, commit on success, otherwise rollback HOT 1
- implement a `pkg:realm:Transaction` like class, simplifying `commit` and `rollback` HOT 3
- Cannot open WAL database via web/wasm HOT 4
- Missleading expection
- Migrate away from `elementAt` for Dart 3.3 HOT 2
- Support for NULL value HOT 1
- sqlcipher_flutter_libs link error in Ubuntu 23.10 and 24.04 HOT 3
- iOS: Could not build Objective-C module 'SQLite3' when install drift HOT 6
- sqlcipher_flutter_libs adding libraries for other platforms in Android build HOT 3
- Target "sqlcipher_flutter_libs_plugin" links to target "Threads::Threads" but the target was not found in linux-arm64
- Migrate web implementation to `dart:js_interop`
- Building to windows with sqlcipher doesn't work in another pc
- SQLCipher does not work on Windows. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sqlite3.dart.