Flutter闲置一段时间后如何执行功能 [英] How to execute a function after a period of inactivity in Flutter

查看:98
本文介绍了Flutter闲置一段时间后如何执行功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个在一段时间不活动后将用户导航到的应用程序.

I need to create an app that navigates a user to after a period of inactivity.

我尝试将我的应用程序包装在GestureDetector中,并在指定的时间段后运行计时器,如下所示,但它不起作用:

I tried wrapping my app in GestureDetector and run a timer after a specified period as shown below but it is not working:

class _MyAppState extends State<MyApp> {
  Timer _timer;

  @override
  void initState() {
    super.initState();

    _initializeTimer();
  }

  void _initializeTimer() {
    _timer = Timer.periodic(const Duration(seconds: 20), (_) => _logOutUser);
  }

  void _logOutUser() {
Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => WelcomePage()));
    _timer.cancel();
  }

  void _handleUserInteraction([_]) {
    if (!_timer.isActive) {
      return;
    }

    _timer.cancel();
    _initializeTimer();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleUserInteraction,
      onPanDown: _handleUserInteraction,
      child: MaterialApp(
        title: 'Hello',
        home: WelcomePage(),
        routes: <String, WidgetBuilder>{
          '/welcome': (BuildContext context) => new WelcomePage(),
          '/login': (BuildContext context) => new LoginPage(),
        },
        debugShowCheckedModeBanner: false,
      ),
    );
  }
}

我的问题是,在Flutter应用程序中一段时间​​不活动之后,我应该如何最好地实现运行功能?

My question is how best should I implement running a function after a period of inactivity within my flutter app?

推荐答案

FWIW,我尝试按照建议使用 GestureDetector ,但是它没有按预期工作.问题是当我没有活动时,我会不断收到手势.这包括当我尝试使用限制性更强的onTap:回调时.

FWIW, I experimented with using a GestureDetector as suggested, but it didn't work as expected. The problem was that I received a continuous stream of gestures when there was no activity. This includes when I tried the more restrictive onTap: callback.

我在仿真器上的调试模式下看到了这一点.我没有做进一步的实验来看看真实的电话是否表现出相同的行为,因为即使现在不行,它们也可能在将来出现:显然,没有任何规范保证GestureDetector 不会会收到虚假事件.对于诸如闲置超时之类的与安全相关的事情,这是不可接受的.

I saw this in debug mode on an emulator. I didn't experiment further to see if real phones manifest the same behavior, because even if they don't now, they might in the future: There's clearly no spec guarantee that a GestureDetector won't receive spurious events. For something security-related like an inactivity timeout, that's not acceptable.

对于我的用例,我认为可以检测到该应用程序什么时候不可见是超过确定的时间量,这是可以的.我对预期使用情况的理由是,真正的危险是当应用程序不可见时,他们忘记了它的存在.

For my use case, I decided that it was OK to instead detect when the application is invisible for more than a set amount of time. My reasoning for my expected usage is that the real danger is when the app is invisible, and they forget it's there.

设置这种不活动超时非常简单.我安排在应用访问敏感信息(例如输入密码后)的那一刻调用 startKeepAlive().就我的使用而言,超时后崩溃退出应用程序是可以的;显然,如果需要的话,可以变得更加复杂.Anyhoo,这是相关代码:

Setting this kind of inactivity timeout is pretty easy. I arrange to call startKeepAlive() at the moment the app gains access to sensitive information (e.g. after a password is entered). For my usage, just crashing out of the app after the timeout is fine; obviously one could get more sophisticated, if needed. Anyhoo, here's the relevant code:

const _inactivityTimeout = Duration(seconds: 10);
Timer _keepAliveTimer;

void _keepAlive(bool visible) {
  _keepAliveTimer?.cancel();
  if (visible) {
    _keepAliveTimer = null;
  } else {
    _keepAliveTimer = Timer(_inactivityTimeout, () => exit(0));
  }
}

class _KeepAliveObserver extends WidgetsBindingObserver {
  @override didChangeAppLifecycleState(AppLifecycleState state) {
    switch(state) {
      case AppLifecycleState.resumed:
        _keepAlive(true);
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        _keepAlive(false);  // Conservatively set a timer on all three
        break;
    }
  }
}

/// Must be called only when app is visible, and exactly once
void startKeepAlive() {
  assert(_keepAliveTimer == null);
  _keepAlive(true);
  WidgetsBinding.instance.addObserver(_KeepAliveObserver());
}

在生产中,我可能会延长超时时间:-)

In production, I'll probably extend the timeout :-)

这篇关于Flutter闲置一段时间后如何执行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆