为什么在 Android 中旋转屏幕时无法终止 setIntervals?
Why setIntervals cannot be killed when the screen was rotated in Android?
各位开发者,
我正在设计一个计时器,它应该能够在屏幕旋转时保持时间,但我注意到以下代码有一个非常奇怪的行为:
function startTimer() {
var setTime = setInterval(function () {
console.log('increasing');
if (isPaused)
clearInterval(setTime);
else {
counter++;
setLocalStorage("counter", counter + 1);
}
}, 1000);
}
function setLocalStorage(key, val) {
if (getLocalStorageValue(key) !== null)
removeLocalStorage(key);
localStorage.setItem(key, val);
}
function getLocalStorageValue(key) {
return localStorage.getItem(key);
}
function removeLocalStorage(key) {
localStorage.removeItem(key);
}
我发现旋转屏幕后,计数器还在不停地增加,控制台甚至没有打印console.log。我想 setInterval 在某个地方并行继续 运行,我找不到停止它的方法,因为我可以将 isPaused
的变量更改为 true
,但计数器仍在继续一个正当的理由,它会停止,直到应用程序完全关闭。你们有没有遇到过类似的事情?
此外,从 Android 方面来看,每次 HTML 页面我都会完全重新加载,那么它不应该保留任何内容,或者您知道每次完全重新加载浏览器的方法吗?
此外,我在 Android 中添加了这段代码,但没有任何反应:
@Override
protected void onDestroy() {
super.onDestroy();
WebView.pauseTimers();
}
感谢您的建议或支持。
经过一些研究,我发现了如何解决这个问题以及发生了什么。
首先如果你是运行一个setInterval
并且旋转屏幕的时候没有在WebView中清空,原来的setInterval
会继续运行 在后台某处,如果您再次旋转它并且您是 运行 第二次计时器,它将创建另一个间隔,依此类推。
如果您希望能够修复它,则需要在每次旋转屏幕时清理页面。我是怎么做到的?
在继续之前的一个小评论,我的解决方案是用 C# 编写的,因为我正在 Xamarin.Android[=50= 中构建应用程序];但是,您可以在眨眼之间将其翻译成 Java 或 Kotlin,它看起来像这样:
声明一个静态变量来检查应用程序是否是第一次恢复:
public static bool RUN_ONCE_RESUME { get; set; } = false;
重写 OnResume
和 OnDestroy
方法如下:
如果不是第一次,OnResume
必须重新启用计时器:
protected override void OnResume()
{
base.OnResume();
if (RUN_ONCE_RESUME)
{
WebView.ResumeTimers();
}
RunOnceResume();
}
OnDestroy
必须杀死整个 WebView
,如下所示:
protected override void OnDestroy()
{
base.OnDestroy();
WebView.RemoveAllViews();
WebView.ClearHistory();
WebView.ClearCache(true);
WebView.LoadUrl("about:blank");
WebView.OnPause();
WebView.RemoveAllViews();
WebView.PauseTimers();
WebView.Destroy();
WebView = null;
}
判断是否是第一次的方法:
private void RunOnceResume()
{
if (!RUN_ONCE_RESUME)
{
RUN_ONCE_RESUME = true;
}
}
我试过没有以前的方法,但它对我的情况不起作用。
通过所有这些更改,计时器将按预期工作。
各位开发者,
我正在设计一个计时器,它应该能够在屏幕旋转时保持时间,但我注意到以下代码有一个非常奇怪的行为:
function startTimer() {
var setTime = setInterval(function () {
console.log('increasing');
if (isPaused)
clearInterval(setTime);
else {
counter++;
setLocalStorage("counter", counter + 1);
}
}, 1000);
}
function setLocalStorage(key, val) {
if (getLocalStorageValue(key) !== null)
removeLocalStorage(key);
localStorage.setItem(key, val);
}
function getLocalStorageValue(key) {
return localStorage.getItem(key);
}
function removeLocalStorage(key) {
localStorage.removeItem(key);
}
我发现旋转屏幕后,计数器还在不停地增加,控制台甚至没有打印console.log。我想 setInterval 在某个地方并行继续 运行,我找不到停止它的方法,因为我可以将 isPaused
的变量更改为 true
,但计数器仍在继续一个正当的理由,它会停止,直到应用程序完全关闭。你们有没有遇到过类似的事情?
此外,从 Android 方面来看,每次 HTML 页面我都会完全重新加载,那么它不应该保留任何内容,或者您知道每次完全重新加载浏览器的方法吗?
此外,我在 Android 中添加了这段代码,但没有任何反应:
@Override
protected void onDestroy() {
super.onDestroy();
WebView.pauseTimers();
}
感谢您的建议或支持。
经过一些研究,我发现了如何解决这个问题以及发生了什么。
首先如果你是运行一个setInterval
并且旋转屏幕的时候没有在WebView中清空,原来的setInterval
会继续运行 在后台某处,如果您再次旋转它并且您是 运行 第二次计时器,它将创建另一个间隔,依此类推。
如果您希望能够修复它,则需要在每次旋转屏幕时清理页面。我是怎么做到的?
在继续之前的一个小评论,我的解决方案是用 C# 编写的,因为我正在 Xamarin.Android[=50= 中构建应用程序];但是,您可以在眨眼之间将其翻译成 Java 或 Kotlin,它看起来像这样:
声明一个静态变量来检查应用程序是否是第一次恢复:
public static bool RUN_ONCE_RESUME { get; set; } = false;
重写
OnResume
和OnDestroy
方法如下:如果不是第一次,
OnResume
必须重新启用计时器:protected override void OnResume() { base.OnResume(); if (RUN_ONCE_RESUME) { WebView.ResumeTimers(); } RunOnceResume(); }
OnDestroy
必须杀死整个WebView
,如下所示:protected override void OnDestroy() { base.OnDestroy(); WebView.RemoveAllViews(); WebView.ClearHistory(); WebView.ClearCache(true); WebView.LoadUrl("about:blank"); WebView.OnPause(); WebView.RemoveAllViews(); WebView.PauseTimers(); WebView.Destroy(); WebView = null; }
判断是否是第一次的方法:
private void RunOnceResume() { if (!RUN_ONCE_RESUME) { RUN_ONCE_RESUME = true; } }
我试过没有以前的方法,但它对我的情况不起作用。
通过所有这些更改,计时器将按预期工作。