On some Android versions the path_provider Pigeon channel
('dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationSupportPath')
is not ready when initDatabasePath() runs before runApp(). The existing code
already catches PlatformException there, leaving _dbPath null — but the
LazyDatabase callback called getApplicationSupportDirectory() a second time
without any protection, causing an unhandled crash on those devices.
Fix: extract _resolveDatabasePath() which retries three times with back-off
(100 ms → 300 ms → 600 ms) before re-throwing with a descriptive error
message. By the time the database is first accessed (after runApp()), the
channel is almost always available; if it still isn't, the CrashScreen is
shown with a clear explanation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1a7b585dd4
commit
8a4ca223e9
@@ -591,15 +591,32 @@ Future<void> initDatabasePath() async {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve the application support path, retrying on PlatformException to
|
||||
/// survive a race where the path_provider Pigeon channel isn't ready yet.
|
||||
Future<String> _resolveDatabasePath() async {
|
||||
if (_dbPath != null) return _dbPath!;
|
||||
// initDatabasePath() failed (channel not ready before runApp). Retry now
|
||||
// that the engine is fully initialised, with brief back-off.
|
||||
const delays = [100, 300, 600];
|
||||
for (final ms in delays) {
|
||||
try {
|
||||
final dir = await getApplicationSupportDirectory();
|
||||
_dbPath = p.join(dir.path, 'sharedinbox.db');
|
||||
return _dbPath!;
|
||||
} on PlatformException {
|
||||
await Future<void>.delayed(Duration(milliseconds: ms));
|
||||
}
|
||||
}
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'path_provider unavailable after ${delays.length + 1} attempts — '
|
||||
'cannot open database.',
|
||||
);
|
||||
}
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
return LazyDatabase(() async {
|
||||
final file = File(
|
||||
_dbPath ??
|
||||
p.join(
|
||||
(await getApplicationSupportDirectory()).path,
|
||||
'sharedinbox.db',
|
||||
),
|
||||
);
|
||||
final file = File(await _resolveDatabasePath());
|
||||
return NativeDatabase.createInBackground(
|
||||
file,
|
||||
setup: (db) {
|
||||
|
||||
Reference in New Issue
Block a user