2013-03-15 38 views
14

Mam animację w mojej aplikacji na Androida, która miga różnymi kolorami w TextView. Użyłem metody TimerTask, Timer i Runnable do zaimplementowania tego. Muszę zatrzymać wątek, gdy użytkownik opuści aplikację podczas animacji onPause(), i wznowić wątek, gdy użytkownik wróci do aplikacji onResume(). Poniżej znajduje się kod, który zaimplementowałem, ale nie działa (elementy onPause() i onResume()) i nie rozumiem dlaczego. Czytałem kilka innych postów w podobnych sprawach, ale nie pomogły mi one dowiedzieć się, co zrobić w mojej sytuacji. Czytałem, że TimerTasks są nieaktualne i prawdopodobnie powinienem użyć metody ExecutorService; nie jest dla mnie jasne, jak wdrożyć tę funkcję.Jak zatrzymać i wznowić TimerTask/Timer

...timerStep5 = new TimerTask() { 

     @Override 
     public void run() { 
      runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
       if (b5) { 
        cashButton2SignalText.setBackgroundColor(Color.RED); 
        cashButton2SignalText.setTextColor(Color.WHITE); 
        b5=false; 
       } else { 
        cashButton2SignalText.setBackgroundColor(Color.WHITE); 
        cashButton2SignalText.setTextColor(Color.RED); 
        b5=true; 
       } 
       } 
      }); 
     } 
}; 

timer5.schedule(timerStep5,250,250); 

} 

public void onPause(){ 

    super.onPause(); 

    timerStep5.cancel(); 

} 

public void onResume(){ 

    super.onResume(); 

    timerStep5.run(); 

} 
+0

Możliwe duplikat [wstrzymywanie/zatrzymywanie i uruchamianie/wznawiania Java TimerTask stale?] (Http://stackoverflow.com/questions/2098642/pausing-stopping-and-starting-resuming-java-timertask-continuously) – Gboy

Odpowiedz

12

Po TimerTask został odwołany, nie można uruchomić ponownie, trzeba utworzyć nową instancję.

szczegóły przeczytać tutaj:

https://stackoverflow.com/a/2098678/727768

ScheduledThreadPoolExecutor jest zalecany do nowszej kodu, obsługuje przypadki takich wyjątków i zadania trwa dłużej niż czas wyznaczonym przedziale.

Ale dla twojego zadania, TimerTask powinno wystarczyć.

+0

Ok, widziałem ten post wcześniej, i myliłem się z tym; może możesz coś dla mnie wyjaśnić: użytkownik może opuścić moją aplikację podczas działania TimerTask i powrócić do tej czynności więcej niż raz. Czy nie oznaczałoby to, że musiałbym utworzyć nowe wystąpienie TimerTask w onResume() za każdym razem, gdy użytkownik opuści to działanie i zwróci? – embersofadyingfire

+0

Pytanie: Jeśli miałbym zignorować działanie użytkownika, który opuścił tę czynność na chwilę i powrócił, i pominął jakąkolwiek implementację, aby wstrzymać i wznowić TimerTask, ale zaimplementował onStop(), aby anulować TimerTask, gdy użytkownik w końcu ruszy do przodu. inną czynnością, czy spowodowałoby to jakiś wyciek pamięci podczas zatrzymania działania TimerTask? – embersofadyingfire

+1

Nie sądzę, że będzie wyciek pamięci, ale nie ma sensu pozwolić, aby zadanie aktualizowania interfejsu użytkownika działało w tle bez niczego. Tak, powinieneś tworzyć w locie TimerTask i nie można go używać ponownie. Został zaprojektowany w ten sposób. (Chyba dla bezpieczeństwa wątków) Również onResume nie jest jakąś szczelną pętlą, koszt stworzenia obiektu jest znikomy. –

2

Oto jak to zrobiłem. Dodaj pauseTimer boolean, gdzie zawsze ma miejsce pauza (być może słuchacz przycisku) i nie licz tego timera, jeśli jest to prawda.

private void timer(){ 
    Timer timer = new Timer(); 
    tv_timer = (TextView) findViewById(R.id.tv_locationTimer); 
    countTimer = 0; 
    timer.scheduleAtFixedRate(new TimerTask() { 
     @Override 
     public void run() { 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        String s_time = String.format("%02d:%02d:%02d", 
          countTimer/3600, 
          (countTimer % 3600)/60, 
          countTimer % 60); 
        tv_timer.setText(s_time); 
        if (!pauseTimer) countTimer++; 
       } 
      }); 
     } 
    }, 1000, 1000); 
}