【问题标题】:Why setIntervals cannot be killed when the screen was rotated in Android?为什么在Android中旋转屏幕时无法杀死setIntervals?
【发布时间】:2018-10-31 20:34:07
【问题描述】:

开发人员,

我正在设计一个Timer,它应该能够在屏幕旋转的情况下保持时间,但是我注意到以下代码的一个非常奇怪的行为:

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

感谢您的建议或支持。

【问题讨论】:

  • 似乎缺少代码的重要部分.... startTime 是否被多次调用?
  • 另外setInterval也不准确...
  • 嗨@epascarello,不,只有当我点击播放时才会多次调用它。
  • 你上面的 setInterval 代码是错误的......所以很难看代码。
  • @epascarello,我添加了缺失的部分。

标签: javascript android timer setinterval screen-rotation


【解决方案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;
        }
    }
    

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多