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

lmt*_*tvt 20 state destroy flutter

我想检测用户何时退出我的应用程序并在之前执行一些代码,但我不知道如何执行此操作。我尝试使用这个包:https : //pub.dev/packages/flutter_lifecycle_state但我有这个错误:

flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lifecycle_state-1.0.0/lib/flutter_lifecycle_state.dart:80:30:错误:找不到Getter:'暂停'。案例 AppLifecycleState.suspending

如果您对此问题有任何解决方案或知道另一种检测用户何时退出我的应用程序的方法,那可能会很酷

Jos*_*ové 17

你现在不能做你想做的事情,无论如何,现在最好的方法是使用 SDK 中的 AppLifecycleState 检查应用程序何时在后台/非活动中运行(基本上是你的库正在尝试做的)

您使用的库已过时,因为 2019 年 11 月的拉取请求AppLifecycleState.suspending称为AppLifecycleState.detached.

您可以在api.flutter.dev网站中查看 AppLifecycleState 枚举

以下是如何观察包含活动的生命周期状态的示例:

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()));
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这段代码将如何帮助询问者**在应用程序退出颤振之前执行代码? (8认同)
  • 暂停!=退出应用程序 (4认同)

Sur*_*gch 8

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

这是来自 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;
  }
}
Run Code Online (Sandbox Code Playgroud)

注意

  • 对于大多数用户来说,退出应用程序通常意味着隐藏它。该应用程序在后台仍处于活动状态,直到系统将其杀死以节省资源。


Wah*_*hyu 7

Scaffold将你的 main/home/top小部件放在一个 中怎么样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)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,WillPopScope 具有禁用 iOS 上“滑动返回”手势的效果,这可能不是我们想要的。此行为也是设计使然(请参阅 https://github.com/flutter/flutter/issues/14203)。相反,您可以使用 WidgetsBindingObserver.didPopRoute,因为这是一个比较低级的级别(有关示例,请参阅 Suragch 的答案)。 (4认同)