离子应用程序中的计时器(setInterval)在后台一段时间后进入睡眠状态 [英] Timers(setInterval) in ionic apps go to sleep after some time in the background

查看:35
本文介绍了离子应用程序中的计时器(setInterval)在后台一段时间后进入睡眠状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 ionic 应用程序有一个计时器(一个简单的 setInterval,每秒滴答一次),当应用程序处于前台时它可以正常工作.但是,当应用程序进入后台并在 10 分钟后回到前台时,应用程序中显示的时间是错误的(时间比应有的要少得多).我尝试将计时器添加到指令中并使用本机 DOM 操作 api(document.getElementById, etc) 方法,但它们都不起作用.我认为当应用程序进入后台时,离子框架正在对视图和绑定做一些事情.有没有人遇到过这样的问题,如果有,你们是如何解决的?

My ionic app has a timer(a simple setInterval that ticks every second) which works perfectly fine when the app is in the foreground. However when the app goes to the background and comes back to the foreground after 10 minutes, the time displayed in the app is wrong (the time is much less that it should be). I have tried adding the timer into a directive and also using the native DOM manipulation api(document.getElementById, etc) methods, but they both didn't work. I think the ionic framework is doing something to the view and bindings when the app goes to the background. Has anyone experience such a issue and if so how did you guys manage to fix it?

推荐答案

经过数小时的寻找答案后,我终于想出了自己的 hack.我希望此解决方案可以帮助遇到类似问题的其他人.

After hours of searching for an answer, I finally came up with my own hack. I hope this solution might help others who come across a similar issue.

当应用程序进入后台时,在某个随机时间,计时器停止计时并进入睡眠状态,直到应用程序返回前台.当应用进入前台时,计时器会从它进入睡眠的那一刻开始再次滴答滴答.

When the app goes to the background, at some random time, the timer stops ticking and goes to sleep till the app is brought back the foreground. When the app comes up to the foreground, the timer starts ticking again from the point where it went to sleep.

    1. 将时间戳记录在一个单独的变量中(以秒为单位),并在计时器的每个时间间隔内更新.

    1. Record the timestamp in a separate variable(in seconds) and have it updated in each interval of the timer.

    var timeStamp = Math.floor(Date.now()/1000);

    var timeStamp = Math.floor(Date.now() / 1000);

    检查计时器的每个时间间隔,如果您前一个时间间隔的时间戳和最新(新)时间间隔之间的差异大于一秒.如果满足条件,请将这两个时间戳之间的差异添加到您的滴答时间.

    Check each interval of the timer if the difference between your previous interval's timeStamp and the latest(new) timeStamp is greater than one second. If the condition is met, add the difference between those two timestamps to your ticking time.

  • 前台应用

    1. 就在计时器开始滴答之前
      - 时间戳记录(假设 1 秒)
    2. 计时器开始计时
      - 检查条件<代码>if(currentTimeStamp - previousTimeStamp > 1){把上面的差加到时间上}在间隔结束之前,使用 currentTimeStamp 更新 TimeStamp 变量.
      在第一个间隔中,currentTimeStamp 应该是 1 秒或 2 秒,具体取决于您将计时器卸载到 setTimeout 中的天气.因此,差异肯定是 0 或 1.由于条件不匹配,我们将时间戳更新为 1 或 2 秒,然后移至下一个间隔.只要计时器不进入睡眠状态,我们的条件就会失败.
    1. Just Before timer start ticking
      - Time stamp recorded (Assume 1 second)
    2. Timers start ticking
      - check condition if(currentTimeStamp - previousTimeStamp > 1) { Add the the above difference to the time } Before the interval ends, update the TimeStamp variable with the currentTimeStamp.
      In the first interval, the currentTimeStamp should be either 1 second or 2 second depending on weather you are offloading the timer into a setTimeout. Thus the difference will definitely be 0 or 1. Since the condition doesn't match we update the timestamp with 1 or 2 seconds and move on to the next interval. As long as the timer doesn't go to sleep our condition will fail.

    后台应用

    奇怪的是,10 分钟后,计时器进入睡眠状态(我们的计时器实际上从现在开始忘记时间了,因为下一个间隔没有触发).

    Strangely after 10 minutes, the timer goes to sleep(our timer is literally losing track of time from now because the next interval is not firing).

    应用从后台返回前台

    计时器从停止的地方开始计时(即下一个间隔).现在我们的条件差异应该超过一秒,因此将差异(基本上是损失的时间)添加到我们当前的滴答时间.

    The timer starts ticking from where it stopped(i.e. the next interval). Now the difference in our condition should be more than one second and thus adding that difference(basically the lost time) to our current ticking time.

  • var transactionTime = 0; //Initial time of timer
    var timeStamp = Math.floor(Date.now() / 1000);
    var deltaDelay = 1;
    
    setInterval(function () {
        if (transactionTime != 0 && (Math.floor(Date.now() / 1000) - timeStamp) > deltaDelay) {
                transactionTime += (Math.floor(Date.now() / 1000) - timeStamp);
            }
            timeStamp = Math.floor(Date.now() / 1000);
    
            //Update your element with the new time.
            window.document.getElementById("transaction_timer").innerHTML = util.formatIntoHHMMSS(transactionTime++);
    
        }, 1000);
    

    注意:此解决方案独立工作(带有原生 DOM api 的 vanilla Js),并且在 angular 指令中也能很好地工作.
    如果您的单线程在其他地方忙于其他任务,您可以将上述代码的 deltaTime 增加到 2 以提高准确度.
    P.s 我实际上是在我自己的 webview 实例中运行 ionic 应用程序而不是cordova,所以我不能使用任何花哨的cordova插件.

    Note: This solution work standalone(vanilla Js with native DOM api) and also works great in angular directives.
    You can increase the deltaTime of the above code to 2 to be a little more accurate if by any chance your single thread is busy somewhere else with some other task.
    P.s I'm actually running the ionic app inside my own instance of a webview and not cordova so I can't use any fancy cordova plugin.

    这篇关于离子应用程序中的计时器(setInterval)在后台一段时间后进入睡眠状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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