为什么在Android中旋转屏幕时无法杀死setIntervals?

时间:2018-10-31 20:34:08

标签: javascript android timer setinterval screen-rotation

资深开发者

我正在设计一个计时器,即使旋转屏幕,它也应该能够保留时间,但是我注意到以下代码的行为很奇怪:

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();
}

感谢您的建议或支持。

1 个答案:

答案 0 :(得分:1)

经过研究,我发现了如何解决此问题以及正在发生的事情。

首先,如果您正在运行setInterval并且在旋转屏幕时未在WebView中清除它,则原始setInterval将继续在后台运行,并且如果再次旋转它,并且第二次运行计时器,它将创建另一个间隔,依此类推。

如果要修复它,您需要在每次旋转屏幕时清洁页面。我是怎么做到的?

在继续之前,有一点评论,我的解决方案是用C#编写的,因为我是在 Xamarin.Android 中构建应用程序的;但是,您可以在眨眼间将其翻译为Java或Kotlin,如下所示:

  1. 声明一个静态变量以检查应用是否是第一次恢复:

    public static bool RUN_ONCE_RESUME { get; set; } = false;
    
  2. 按如下所示覆盖OnResumeOnDestroy方法:

    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;
    }
    
  3. 检查是否为第一次的方法:

    private void RunOnceResume()
    {
        if (!RUN_ONCE_RESUME)
        {
            RUN_ONCE_RESUME = true;
        }
    }
    

我尝试不使用以前的方法,但在我的情况下不起作用。

通过所有这些更改,计时器将按预期工作。