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

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

问题描述

我的离子应用程序有一个计时器(一个简单的setInterval,它每秒钟滴答一次),当该应用程序在前台时,它可以很好地工作.但是,当应用程序进入后台并在10分钟后返回到前台时,应用程序中显示的时间是错误的(该时间要少得多).我尝试将计时器添加到指令中,还尝试使用本机DOM操作api(document.getElementById等)方法,但它们均无效.我认为当应用程序进入后台时,离子框架正在对视图和绑定进行某些操作.有人遇到过这样的问题吗?如果是这样,你们是如何设法解决的?

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?

推荐答案

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

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);

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

    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) { Add the the above difference to the time } Before the interval ends, update the TimeStamp variable with the currentTimeStamp.
      在第一个间隔中,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,以使其更加准确.
    附言:我实际上是在自己的Web视图实例中运行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.

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

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