アプリのJavaScriptが報告した途方もなく長い読み込み時間を追跡していたところ、ウィンドウがバックグラウンドにあるとき、またはディスプレイがオフのときに、Android(およびiOS)がJavaScriptの実行を一時停止することがわかりました。
Androidでは、window.onfocus
イベントとonblur
イベントを使用して、アプリがバックグラウンドに切り替わったことを検出できることがわかりました(少なくとも、新しいスクリプトの場合、jsの実行はすぐに一時停止されます)。画面がオンまたはオフになったことを検出する方法が見つかりません。これは可能ですか?
(Safariでは、onfocus
とonblur
が確実に起動しなかったことを除いて、同様の結果が得られました。)
それをチェックするいくつかのオプションがあります:
focus
およびblur
イベントを使用して、ブラウザータブの可視性を検出します。
window.addEventListener( "focus"、handleBrowserState.bind(context、true)); window.addEventListener( "blur"、handleBrowserState.bind(context、false)); function handleBrowserState(isActive){ //何かをする }
私は自分のユースケースにかなり良い解決策を見つけました:
function getTime() {
return (new Date()).getTime();
}
var lastInterval = getTime();
function intervalHeartbeat() {
var now = getTime();
var diff = now - lastInterval;
var offBy = diff - 1000; // 1000 = the 1 second delay I was expecting
lastInterval = now;
if(offBy > 100) { // don't trigger on small stutters less than 100ms
console.log('interval heartbeat - off by ' + offBy + 'ms');
}
}
setInterval(intervalHeartbeat, 1000);
画面がオフになると(または何らかの理由でJSが一時停止されると)、次の間隔はJSの実行が再開されるまで遅延されます。私のコードでは、タイマーをoffBy
の量だけ調整して、それを適切と呼ぶことができます。
簡単なテストでは、これはAndroid 4.2.2のブラウザとiOS6.1.3のSafariの両方でうまく機能するようでした。
ここで素敵な関数が見つかりました:
http://rakaz.nl/2009/09/iphone-webapps-101-detecting-essential-information-about-your-iphone.html
(function() {
var timestamp = new Date().getTime();
function checkResume() {
var current = new Date().getTime();
if (current - timestamp > 4000) {
var event = document.createEvent("Events");
event.initEvent("resume", true, true);
document.dispatchEvent(event);
}
timestamp = current;
}
window.setInterval(checkResume, 1000);
})();
イベントに登録するには:
addEventListener("resume", function() {
alert('Resuming this webapp');
});
これは、resume
イベントも発生させるCordovaと一致しています。
画面がオフになったら、スクリプトで何をしますか?とにかく、Javaオブジェクト( http://developer.Android.com/reference/Android/webkit/WebView.html#addJavascriptInterface(Java.lang.Object、 %20Java.lang.String) )アクティビティとインターフェイスし、JSの世界で必要なすべての情報をプロキシします。