問題の背景:
H5 ページにビデオ情報がある場合があります。ページが終了した後もビデオが再生され続けるという問題を解決するために、ページが破棄されたときに WebView で、pauseTimers
操作
問題の説明:
同時に 2 つの WebView ページを開き、2 番目のページを閉じると、最初のページの一部の操作が応答しなくなります。
まず、この問題のpauseTimers
原因は、pauseTimers
すべての WebView が中断されるためですlayout
。parsing
またJavaScript timers
、これはグローバルに有効なメソッドであるため、最初のページの js メソッドも中断されます(このステートメントは誤りであり、以下で修正して説明します)。 . しかし、プログラムはページ上にonResume
あるときにresumeTimers
restore jsメソッドを呼び出しますが、なぜ有効にならないのでしょうか?
さらに分析した結果、この問題の原因には、ページが切り替わる際のライフサイクルの実行順序も含まれていることがわかりました。ページ A が開かれ、次にページ B が開かれ、この時点でページ B が閉じられたと仮定すると、2 つのページのライフサイクル実行シーケンスは次のようになりますB:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy
。
ここから、ページ Bを閉じた後、最初にページ A に入っonResume
てresumeTimers
、次にページ B に入っonDestroy
てわかります。pauseTimers
したがって、最終的な実行は、pauseTimers
グローバル WebView が js の呼び出しを停止するという結果になります。
解決:
ページが のときに呼び出されるpauseTimers
メソッドを変更します。onPause
思考を広げる:
調査pauseTimers
の、すべての js メソッドをグローバルに一時停止することについて多くの人が理解していることがわかりました。これは、インターネット上でも一般的なことわざです。しかし、テスト中に、これが当てはまらないことがわかりました.たとえば、テスト中にhtmlページを書きました.2つのjsメソッドを呼び出すことに対応する2つのボタンがあり、1つはH5でアラートポップアップウィンドウを呼び出すことです. 、もう 1 つは Android を呼び出すことです。メソッドはトーストをポップアップ表示します。2 つの js メソッドは、呼び出しpauseTimers
後も。html コードは次のとおりです。
<html>
<body>
<button style="width:100px;height:50px;" onclick="jsAlert()">alert</button>
<button style="width:100px;height:50px;" onclick="androidToast()">toast</button>
</body>
</html>
<script>
function jsAlert() {
alert("Can Alert!");
}
function androidToast() {
window.market.showToast("Can Toast!");
}
</script>
そのため、の実際の機能pauseTimers
について。コメントに記載されているように、Pauses all layout, parsing, and JavaScript timers for all WebViews.
文字通りjsメソッドを参照していませんが、タイマーなどを参照しているようです。JavaScript timers
そこで、html でタイマーを実装するさらなるテストを次に示します。
<html>
<body>
<button style="width:100px;height:50px;" onclick="startTimer()">start</button>
<button style="width:100px;height:50px;" onclick="resetTimer()">reset</button>
<button style="width:100px;height:50px;" onclick="jsAlert()">alert</button><br><br>
<input style="width:100px;height:50px;" value="0" id="show_num">
</body>
</html>
<script>
var timer = null;
var num = 0;
function startTimer() {
timer = setInterval(function() {
document.getElementById("show_num").value = ++num;
}, 1000);
}
function resetTimer() {
clearInterval(timer);
document.getElementById("show_num").value = 0;
countdown = null;
num = 0;
}
function jsAlert() {
alert("Can Alert!");
}
</script>
Android に 2 つのボタンを実装して、それぞれ WebViewpauseTimers
とresumeTimers
メソッドを呼び出します。
findViewById(R.id.pause).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mWebView.pauseTimers();
}
});
findViewById(R.id.resume).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mWebView.resumeTimers();
}
});
テストを
開始するには、まず H5 ページの開始ボタンをクリックすると、H5 ページのタイマーがカウントを開始します. この時点でアラートをクリックすると、ポップアップ ウィンドウが表示されます. 次に、ネイティブ インターフェースの一時停止ボタンをクリックしてpauseTimers
操作、H5 ページのタイマーが一時停止していることを確認します。アラート ポップアップ ウィンドウは、この時点でも引き続き表示されます。次に、ネイティブ インターフェースの再開ボタンをクリックしてresumeTimers
操作と、H5 ページのタイマーが引き続きカウントされます。
pauseTimers
上記の調査プロセスを通じて、 js でタイマーを一時停止するだけでは js メソッドの呼び出しと応答に影響しないことがわかり、 「pauseTimers
グローバル js を停止できる」という記述は正しくありません。ページ上の一部の操作が応答しないという前述の問題はlayout
、parsing
内部ジャンプ、ページ レンダリングなど、WebView に関連するか、WebView に関連している可能性があります。