ionic应用程序中的计时器(setInterval)在后台运行一段时间后进入睡眠状态

Timers(setInterval) in ionic apps go to sleep after some time in the background

本文关键字:一段时间 运行 状态 后台 应用程序 计时器 setInterval ionic      更新时间:2023-09-26

我的ionic应用程序有一个计时器(一个简单的setInterval每秒滴答),当应用程序在前台时,它工作得很好。然而,当应用程序进入后台并在10分钟后返回前台时,应用程序中显示的时间是错误的(时间比应该的要少得多)。我曾尝试将计时器添加到指令中,并使用本机DOM操作api(文档)。getElementById等)方法,但它们都不起作用。我认为ionic框架在应用进入后台时对视图和绑定做了一些事情。有人遇到过这样的问题吗?如果有,你们是如何解决的?

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

当应用程序进入后台时,在某个随机时间,计时器停止滴答并进入睡眠状态,直到应用程序被带回前台。当应用程序进入前台时,计时器从它进入睡眠状态的位置开始再次滴答作响。

  • <标题>解决方案/黑客:
    1. 将时间戳记录在一个单独的变量中(以秒为单位),并在计时器的每个间隔中更新。

    2. var timeStamp = Math.floor(Date.now()/1000);
    3. 检查定时器的每个间隔,如果你的前一个间隔的时间戳和最新的(新的)时间戳之间的差异大于1秒。如果满足条件,则将这两个时间戳之间的差值添加到您的滴答时间。

  • 工作原理:

    App in前台

    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秒更新时间戳,并继续到下一个间隔。只要计时器不休眠,我们的条件就会失效。

    App in Background

    奇怪的是,10分钟后,计时器进入睡眠状态(我们的计时器从现在开始失去时间跟踪,因为下一个间隔没有触发)。

    App从后台返回前台

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

  • <标题>代码:
    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的香草Js),并且在angular指令中也可以很好地工作。
    你可以把上面代码的deltaTime增加到2,如果你的单线程碰巧在其他地方忙于其他任务,那么就会更准确一些。
    P。我实际上是在我自己的webview实例中运行ionic应用程序,而不是cordova,所以我不能使用任何花哨的cordova插件

  • Ionic/Cordova应用程序在后台模式下进入睡眠状态。但是你可以看看这个:https://github.com/katzer/cordova-plugin-background-mode

    下面是来自原来答案

    var interval = null;
    var timerSecondsTotal = 0;
    function runTimer() {
          var prevTickTimestamp = Date.now()
          interval = setInterval(() => {
            var currentTickTimestamp = Date.now()
            var delta = currentTickTimestamp - prevTickTimestamp
            timerSecondsTotal += Math.round(delta / 1000)
            prevTickTimestamp = currentTickTimestamp
          }, 1000)
        }