当iPhone/Android进入睡眠状态时,JavaScript执行(settimeout等)会发生什么变化?

当iPhone/Android进入睡眠状态时,JavaScript执行(settimeout等)会发生什么变化?,android,ios,web-applications,mobile,settimeout,Android,Ios,Web Applications,Mobile,Settimeout,我有一个jQuery移动web应用程序,它的目标是iOS和Android设备。应用程序的一个组件是后台任务,它定期检查A.)本地数据的更改和b.)与服务器的连接。如果两者都为真,则任务将推动更改 我使用一个简单的基于setTimeout()的函数来执行此任务。每个失败或成功条件都会对后台任务调用setTimeout(),确保它以30秒的间隔运行。出于调试目的,我使用最后一个任务运行时的时间戳更新status div 在任何桌面浏览器中,这都可以正常工作;但是,在iOS或Android上,经过一段

我有一个jQuery移动web应用程序,它的目标是iOS和Android设备。应用程序的一个组件是后台任务,它定期检查A.)本地数据的更改和b.)与服务器的连接。如果两者都为真,则任务将推动更改

我使用一个简单的基于setTimeout()的函数来执行此任务。每个失败或成功条件都会对后台任务调用setTimeout(),确保它以30秒的间隔运行。出于调试目的,我使用最后一个任务运行时的时间戳更新status div

在任何桌面浏览器中,这都可以正常工作;但是,在iOS或Android上,经过一段时间后,任务停止执行。我想知道这是否与设备的节能设置有关——当iOS进入待机状态时,是否会终止JavaScript执行?这似乎就是发生的情况


如果是这样,最好的恢复方式是什么?有我可以参加的守夜活动吗?如果没有,还有哪些其他选项不涉及与依赖于用户交互的事件挂钩(我不想将整个页面绑定到一个点击事件,只是为了重新启动后台任务)。

看起来,当浏览器页面未聚焦时,Javascript执行会在MobileSafari上暂停。另外,如果setInterval()事件延迟,那么只要浏览器聚焦,就会立即触发这些事件。这意味着我们应该能够保持setInterval()的运行,并假设如果setInterval函数花费的时间比平时长得多,浏览器就会失去/恢复焦点

此代码在从浏览器选项卡切换回、从其他应用切换回以及从睡眠中恢复后发出警报。如果您将阈值设置为比setTimeout()稍长一点,则可以假定如果触发此操作,超时将不会结束

<script type="text/javascript">
var lastCheck = 0;

function sleepCheck() {
        var now = new Date().getTime();
        var diff = now - lastCheck;
        if (diff > 3000) {
                alert('took ' + diff + 'ms');
        }
        lastCheck = now;
}

window.onload = function() {
        lastCheck = new Date().getTime();
        setInterval(sleepCheck, 1000);
}
</script>
如果您想保持安全:您可以保存超时ID(由setTimeout返回),并将其设置为比超时短的阈值,然后在触发时再次运行clearTimeout()和setTimeout()

<script type="text/javascript">
var lastCheck = 0;

function sleepCheck() {
        var now = new Date().getTime();
        var diff = now - lastCheck;
        if (diff > 3000) {
                alert('took ' + diff + 'ms');
        }
        lastCheck = now;
}

window.onload = function() {
        lastCheck = new Date().getTime();
        setInterval(sleepCheck, 1000);
}
</script>

var lastCheck=0;
函数sleepCheck(){
var now=new Date().getTime();
var diff=现在-最后一次检查;
如果(差值>3000){
警报('take'+diff+'ms');
}
lastCheck=现在;
}
window.onload=函数(){
lastCheck=新日期().getTime();
设置间隔(睡眠检查,1000);
}
编辑:看起来这有时会在简历上连续触发多次,所以你需要以某种方式处理。(在让我的android浏览器睡了一整夜后,它醒了两个alert()s。我打赌Javascript在完全睡眠前的某个任意时间恢复了。)


我在安卓2.2和最新的iOS上进行了测试,它们都会在你从睡眠中恢复时发出警报。

看起来,当浏览器页面未聚焦时,Javascript在MobileSafari上的执行会暂停。另外,如果setInterval()事件延迟,那么只要浏览器聚焦,就会立即触发这些事件。这意味着我们应该能够保持setInterval()的运行,并假设如果setInterval函数花费的时间比平时长得多,浏览器就会失去/恢复焦点

此代码在从浏览器选项卡切换回、从其他应用切换回以及从睡眠中恢复后发出警报。如果您将阈值设置为比setTimeout()稍长一点,则可以假定如果触发此操作,超时将不会结束

<script type="text/javascript">
var lastCheck = 0;

function sleepCheck() {
        var now = new Date().getTime();
        var diff = now - lastCheck;
        if (diff > 3000) {
                alert('took ' + diff + 'ms');
        }
        lastCheck = now;
}

window.onload = function() {
        lastCheck = new Date().getTime();
        setInterval(sleepCheck, 1000);
}
</script>
如果您想保持安全:您可以保存超时ID(由setTimeout返回),并将其设置为比超时短的阈值,然后在触发时再次运行clearTimeout()和setTimeout()

<script type="text/javascript">
var lastCheck = 0;

function sleepCheck() {
        var now = new Date().getTime();
        var diff = now - lastCheck;
        if (diff > 3000) {
                alert('took ' + diff + 'ms');
        }
        lastCheck = now;
}

window.onload = function() {
        lastCheck = new Date().getTime();
        setInterval(sleepCheck, 1000);
}
</script>

var lastCheck=0;
函数sleepCheck(){
var now=new Date().getTime();
var diff=现在-最后一次检查;
如果(差值>3000){
警报('take'+diff+'ms');
}
lastCheck=现在;
}
window.onload=函数(){
lastCheck=新日期().getTime();
设置间隔(睡眠检查,1000);
}
编辑:看起来这有时会在简历上连续触发多次,所以你需要以某种方式处理。(在让我的android浏览器睡了一整夜后,它醒了两个alert()s。我打赌Javascript在完全睡眠前的某个任意时间恢复了。)


我在Android 2.2和最新的iOS上进行了测试,它们都会在你从睡眠状态恢复时发出警报。

当用户切换到另一个应用程序或屏幕睡眠时,计时器似乎会暂停,直到用户切换回应用程序(或屏幕唤醒时)

Phonegap有一个事件,你可以听它,而不是轮询状态(如果你想在它失去焦点之前做一些事情,也有一个事件)。你开始听它后,DeviceRady火灾

document.addEventListener("deviceready", function () {
    // do something when the app awakens
    document.addEventListener('resume', function () {
        // re-create a timer.
        // ...
    }, false);
}, false);
我将angular与phonegap一起使用,并且实现了一个服务,可以为我管理特定的超时,但基本上,您可以创建一个对象来设置计时器、取消计时器,最重要的是更新计时器(更新是在“恢复”事件期间调用的内容)

在angular中,我有一个可以附加数据的作用域和根作用域,我的超时是全局的,所以我将它附加到根作用域,但出于本例的目的,我只将它附加到document对象。我不允许这样做,因为您需要将它应用于某种范围或名称空间

var timeoutManager = function () {
    return {
        setTimer: function (expiresMsecs) {
            document.timerData = {
                timerId: setTimeout(function () {
                    timeoutCallback();
                },
                expiresMsecs),

                totalDurationMsecs: expiresMsecs,
                expirationDate: new Date(Date.now() += expiresMsecs)
            };
        },

        updateTimer: function () {
            if (document.timerData) {
                //
                //  Calculate the msecs remaining so it can be used to set a new timer.
                //
                var timerMsecs = document.timerData.expirationDate - new Date();

                //
                //  Kill the previous timer because a new one needs to be set or the callback
                //  needs to be fired.
                //
                this.cancelTimer();

                if (timerMsecs > 0) {
                    this.setTimer(timerMsecs);
                } else {
                    timeoutCallback();
                }
            }
        },

        cancelTimer: function () {
            if (document.timerData && document.timerData.timerId) {
                clearTimeout(document.timerData.timerId);
                document.timerData = null;
            }
        }
    };
};
您可以让manager函数获取毫秒参数,而不是将其传递到集合中,但这在某种程度上是按照我编写的angular service建模的。操作应该足够清晰和简洁,可以对它们进行处理,并将它们添加到您自己的应用程序中

var timeoutCallback = function () { console.log('timer fired!'); };
var manager = timeoutManager();
manager.setTimer(20000);
一旦在事件侦听器中获得resume事件,您将需要更新计时器,如下所示:

// do something when the app awakens
document.addEventListener('resume', function () {
    var manager = timeoutManager();
    manager.updateTimer();
}, false);

超时管理器还具有
cancelTimer()
,可用于随时终止计时器。

当用户切换到另一个应用程序或屏幕休眠时,计时器似乎会暂停,直到用户切换回应用程序(或当屏幕