如何在应用程序退出Flutter之前执行代码

jpfvwuh4  于 2023-05-23  发布在  Flutter
关注(0)|答案(6)|浏览(402)

我想检测用户何时退出我的应用程序并在之前执行一些代码,但我不知道如何做到这一点。我试着用这个包:https://pub.dev/packages/flutter_lifecycle_state,但我有这个错误:
http:pub.dartlang.org/flutter_lifecycle_state-1.0.0/lib/flutter_lifecycle_state.dart:80:30:错误:找不到Getter:“暂停”case AppLifecycleState.挂起
如果您有任何解决方案,或者知道另一种方法来检测用户何时退出我的应用,这可能是很酷的

z2acfund

z2acfund1#

你现在不能做你想做的事情,无论如何,现在最好的方法是使用SDK中的AppLifecycleState来检查应用程序何时在后台运行/处于非活动状态(基本上做你的库正在尝试做的事情)
你正在使用的库已经过时了,因为2019年11月的一个pull请求将AppLifecycleState.suspending命名为AppLifecycleState.detached
您可以查看api.flutter.dev网站中的AppLifecycleState枚举
下面是如何观察包含Activity的生命周期状态的示例:

import 'package:flutter/widgets.dart';

class LifecycleWatcher extends StatefulWidget {
  @override
  _LifecycleWatcherState createState() => _LifecycleWatcherState();
}

class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

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

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null)
      return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr);

    return Text('The most recent lifecycle state this widget observed was: $_lastLifecycleState.',
        textDirection: TextDirection.ltr);
  }
}

void main() {
  runApp(Center(child: LifecycleWatcher()));
}

我认为删除你的数据在非活动周期,然后创建它再次在恢复的一个可以为你工作。

mu0hgdu0

mu0hgdu02#

audio_service插件做的事情非常相似。策略是将应用 Package 在一个自定义小部件中,该小部件监听应用生命周期状态何时发生变化,然后根据状态运行不同的代码。我不是说你应该使用这个插件,但你可以调整代码,以满足您的需要。将下面对AudioService的引用替换为您需要运行的任何代码。
下面是the code from audio_service

/// A widget that maintains a connection to [AudioService].
///
/// Insert this widget at the top of your `/` route's widget tree to maintain
/// the connection across all routes. e.g.
///
/// ```
/// return MaterialApp(
///   home: AudioServiceWidget(MainScreen()),
/// );
/// ```
///
/// Note that this widget will not work if it wraps around [MateriaApp] itself,
/// you must place it in the widget tree within your route.
class AudioServiceWidget extends StatefulWidget {
  final Widget child;

  AudioServiceWidget({@required this.child});

  @override
  _AudioServiceWidgetState createState() => _AudioServiceWidgetState();
}

class _AudioServiceWidgetState extends State<AudioServiceWidget>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    AudioService.connect();
  }

  @override
  void dispose() {
    AudioService.disconnect();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        AudioService.connect();
        break;
      case AppLifecycleState.paused:
        AudioService.disconnect();
        break;
      default:
        break;
    }
  }

  @override
  Future<bool> didPopRoute() async {
    AudioService.disconnect();
    return false;
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

注意

  • 对于大多数用户来说,退出应用程序通常只是意味着隐藏它。应用程序在后台仍然活跃,直到系统杀死它以保存资源。
p1tboqfb

p1tboqfb3#

把你的main/home/top Scaffold小部件放在WillPopScope里面怎么样?

class MyGreatestApp extends StatefulWidget {
  @override
  _MyGreatestAppState createState() => _MyGreatestAppState();
}

class _MyGreatestAppState extends State<MyGreatestApp> {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      child: Scaffold(...),
      onWillPop: _doNastyStuffsBeforeExit,
    );
  }

  Future<bool> _doNastyStuffsBeforeExit() async{
    // Since this is an async method, anything you do here will not block UI thread
    // So you should inform user there is a work need to do before exit, I recommend SnackBar

    // Do your pre-exit works here...

    // also, you must decide whether the app should exit or not after the work above, by returning a future boolean value:

    return Future<bool>.value(true); // this will close the app,
    return Future<bool>.value(false); // and this will prevent the app from exiting (by tapping the back button on home route)
  }
}
omtl5h9j

omtl5h9j4#

1-)首先在有状态小部件中使用WidgetsBindingObserver,关键字为“with”。
2-)在initState中使用WidgetsBinding.instance.addObserver(this);初始化WidgetsBinding
3-)在您的部署中使用WidgetsBinding.instance.removeObserver(this);部署控件绑定。
4-)最后,使用didChangeAppLifecycleState检查用户是否离开了应用程序。下面的例子;

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        //Execute the code here when user come back the app.
        //In my case, I needed to show if user active or not,
        FirebaseMethods().updateLiveStatus(_authInstance.currentUser.uid, true);
        break;
      case AppLifecycleState.paused:
        //Execute the code the when user leave the app
        FirebaseMethods()
            .updateLiveStatus(_authInstance.currentUser.uid, false);
        break;
      default:
        break;
    }
  }

  @override
  Widget build(BuildContext context) {}
}
41ik7eoe

41ik7eoe5#

我在Android端的一个插件中实现了类似的东西,这个想法是你需要使用Flutters MethodChannel类,然后从本地端调用你想要在应用程序关闭之前从Flutter端执行的方法。
在我的例子中,我实现了对onDetachedFromActivity的重写,它在Flutter引擎分离之前被调用。此方法位于io.flutter.embedding.engine.plugins.activity.ActivityAware接口

laawzig2

laawzig26#

在我的测试中,WidgetsBinfing无法检测到onDestory。我认为Flutters MethodChannel是最好的方式来完成特定的功能时,应用程序的onDestory。(巴塞尔Abuhadrous回答)

相关问题