Merge pull request #527 from krille-chan/krille/better-background-fetch-android
feat: Background fetch mode on Android
This commit is contained in:
commit
6765fb0150
1 changed files with 53 additions and 2 deletions
|
|
@ -5,6 +5,7 @@ import 'package:flutter_app_lock/flutter_app_lock.dart';
|
|||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/utils/client_manager.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'config/setting_keys.dart';
|
||||
|
|
@ -13,7 +14,7 @@ import 'widgets/fluffy_chat_app.dart';
|
|||
import 'widgets/lock_screen.dart';
|
||||
|
||||
void main() async {
|
||||
Logs().i('Welcome to FluffyChat');
|
||||
Logs().i('Welcome to ${AppConfig.applicationName} <3');
|
||||
|
||||
// Our background push shared isolate accesses flutter-internal things very early in the startup proccess
|
||||
// To make sure that the parts of flutter needed are started up already, we need to ensure that the
|
||||
|
|
@ -28,9 +29,34 @@ void main() async {
|
|||
await firstClient?.roomsLoading;
|
||||
await firstClient?.accountDataLoading;
|
||||
|
||||
// If the app starts in detached mode, we assume that it is in
|
||||
// background fetch mode for processing push notifications. This is
|
||||
// currently only supported on Android.
|
||||
if (PlatformInfos.isAndroid &&
|
||||
AppLifecycleState.detached == WidgetsBinding.instance.lifecycleState) {
|
||||
// In the background fetch mode we do not want to waste ressources with
|
||||
// starting the Flutter engine but process incoming push notifications.
|
||||
BackgroundPush.clientOnly(clients.first);
|
||||
// To start the flutter engine afterwards we add an custom observer.
|
||||
WidgetsBinding.instance.addObserver(AppStarter(clients));
|
||||
Logs().i(
|
||||
'${AppConfig.applicationName} started in background-fetch mode. No GUI will be created unless the app is no longer detached.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Started in foreground mode.
|
||||
Logs().i(
|
||||
'${AppConfig.applicationName} started in foreground mode. Rendering GUI...',
|
||||
);
|
||||
await startGui(clients);
|
||||
}
|
||||
|
||||
/// Fetch the pincode for the applock and start the flutter engine.
|
||||
Future<void> startGui(List<Client> clients) async {
|
||||
// Fetch the pin for the applock if existing for mobile applications.
|
||||
String? pin;
|
||||
if (PlatformInfos.isMobile) {
|
||||
BackgroundPush.clientOnly(clients.first);
|
||||
try {
|
||||
pin =
|
||||
await const FlutterSecureStorage().read(key: SettingKeys.appLockKey);
|
||||
|
|
@ -39,6 +65,9 @@ void main() async {
|
|||
}
|
||||
}
|
||||
|
||||
// Start rendering the Flutter app and wrap it in an Applock.
|
||||
// We do this only for mobile applications as we saw routing
|
||||
// problems on other platforms if we wrap it always.
|
||||
runApp(
|
||||
PlatformInfos.isMobile
|
||||
? AppLock(
|
||||
|
|
@ -49,3 +78,25 @@ void main() async {
|
|||
: FluffyChatApp(clients: clients),
|
||||
);
|
||||
}
|
||||
|
||||
/// Watches the lifecycle changes to start the application when it
|
||||
/// is no longer detached.
|
||||
class AppStarter with WidgetsBindingObserver {
|
||||
final List<Client> clients;
|
||||
bool guiStarted = false;
|
||||
|
||||
AppStarter(this.clients);
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (guiStarted) return;
|
||||
if (state == AppLifecycleState.detached) return;
|
||||
|
||||
Logs().i(
|
||||
'${AppConfig.applicationName} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...',
|
||||
);
|
||||
startGui(clients);
|
||||
// We must make sure that the GUI is only started once.
|
||||
guiStarted = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue