Flutter Background Service如何判断应用程序从后台返回到前台?

vc6uscn9  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(622)

我想要实现的:

  • 判断应用程序在后台服务中处于后台还是前台;

我尝试过的:

  • 我发现在使用WidgetBindingObserver来检测应用程序的周期时,无法更改后台服务;

这是我目前检测应用程序的周期:

@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    debugPrint('App State = $state');
    DbUserUranus? user = AppData.instance()!.user;
    if (user != null) {
      if (state == AppLifecycleState.inactive ||
          state == AppLifecycleState.paused) {
        ChatApp.instance()!
            .eventsSender
            .sendPresence(PresenceType.Away, user.user_addr);
        GlobalSettings.isAppInBackground = true;
        debugPrint("----------------- ^^^^^^^^^^ App in background!!");

      } else if (state == AppLifecycleState.resumed) {
        // MQTTClientWrapper.instance().connect();

        ChatApp.instance()!
            .eventsSender
            .sendPresence(PresenceType.Available, user.user_addr);
        GlobalSettings.isAppInBackground = false;
        debugPrint("---------------- ^^^^^^^^^^^ App comes back!");
      }
    }
  }

问题是,我从主线程更改的值,在后台服务线程中不生效。
如何启动后台服务:

if (Platform.isAndroid) {
    debugPrint("now... to the background service!!!");
    var channel = const MethodChannel('com.example/background_service');
    // var serviceInst = MQTTService.instance();
    // var backgroundMain = serviceInst.startListen();
    var callbackHandle =
    PluginUtilities.getCallbackHandle(backgroundMain);
    channel.invokeMethod('startService', callbackHandle?.toRawHandle());
  }

任何建议将非常感谢!

cbjzeqam

cbjzeqam1#

我使用了Isolate和flutter_background_service插件。
您可以通过以下方式实现这一点:
1.在后台服务中设置一个带有ValueNotifier的接收器,它将接收来自UI的事件
1.在后台服务中设置一个带有ValueNotifier的bool,这将用于跟踪应用程序的状态。
1.在UI中,使用WidgetsBindingObserver类扩展小部件,这将用于捕获应用程序生命周期事件(恢复、暂停、非活动等)
1.在initState方法中注册观察者。
1.重写didChangeAppLifecycleState事件,一旦应用程序的生命周期状态被更改,就会触发这个事件,它有一个状态参数,你可以使用它来获取应用程序的当前状态。
UI类:
class _ExampleState使用WidgetsBindingObserver扩展State {
_sendPort;

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this);
  ...
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  _sendPort ??= IsolateNameServer.lookupPortByName('appState');
  switch(state){
    case AppLifecycleState.resumed:
      _sendPort?.send(false);
      break;
    case AppLifecycleState.paused:
      _sendPort?.send(true);
      break;
    default:
      break;
  }
}

服务:

class RideBackgroundService {
  static final ValueNotifier<bool> _appPausedState = ValueNotifier<bool>(false);
  static final ValueNotifier<ReceivePort?> _stateNotifier = ValueNotifier<ReceivePort?>(null);

  ...

  static void onStart(ServiceInstance service) {
    if(_stateNotifier.value == null){
      _stateNotifier.value = ReceivePort('appState');
      IsolateNameServer.registerPortWithName(_stateNotifier.value!.sendPort, 'appState');
      _stateNotifier.value?.listen((dynamic value) {
        _appPausedState.value = serviceInfo.value as bool;
      });
    }
    ...
  }

然后,您可以使用_appPauseState.值来查看应用程序的状态。请记住,它不可能发送示例,您应该使用基本的数据类型,如int,或者您可以将对象转换为map并发送。
你也可以通过一个无状态的小部件来做到这一点,我不认为它必须是一个statefull小部件,我只是在我的项目中使用了一个statefull小部件。
你也可以修改这段代码,发送一个int而不是bool来获取所有的状态。

相关问题