Почему setIntervals нельзя убить при повороте экрана в Android? - PullRequest
0 голосов
/ 31 октября 2018

Товарищи-разработчики,

Я разрабатываю таймер, который должен сохранять время даже при повороте экрана, но я заметил очень странное поведение со следующим кодом:

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 голосов
/ 01 ноября 2018

После некоторых исследований я нашел, как решить проблему и что происходит.

Прежде всего, если вы запускаете setInterval, и вы не очищаете его в WebView при повороте экрана, исходный setInterval будет продолжать работать где-то в фоновом режиме, и если вы поворачиваете его снова, и вы запускаете таймер во второй раз, он создаст другой интервал и так далее, и так далее.

Если вы хотите исправить это, вам нужно чистить страницу каждый раз при повороте экрана. Как я это сделал?

Небольшой комментарий, прежде чем продолжить, мое решение написано на C #, так как я создаю приложение на Xamarin.Android ; однако, вы можете перевести его на Java или Kotlin в мгновение ока, и это выглядит так:

  1. Объявите статическую переменную для проверки, возобновляет ли приложение в первый раз или нет:

    public static bool RUN_ONCE_RESUME { get; set; } = false;
    
  2. Переопределите методы 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;
    }
    
  3. Методы проверки, если это в первый раз или нет:

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

Я пытался без предыдущего метода, и он не работал в моем случае.

Со всеми этими изменениями таймер будет работать как положено.

...