2011-12-06 3 views
1

특정 간격으로 특정 작업을 실행해야하는 시나리오가 있습니다. 그러나 재실행하지 않고 타이머를 재설정/재시작 할 수 있기를 원합니다. 더 나은 이해를위한 제 코드가 있습니다.재설정 옵션이있는 Android java.util.Timer

private TimerTask beatTask = new TimerTask() { 
     @Override 
     public void run() { 
      beatDetected(); 
     } 
    }; 

public void beatDetected() { 
     timeoutTimer.cancel(); 

     // handle my stuff and restart the timer. 

     timeoutTimer.schedule(beatTask, 2000); 
    } 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

     (timeoutTimer = new Timer()).schedule(beatTask, 2000); 

     return Service.START_STICKY; 
    } 

이 구현 뒤에 아이디어는 beatDetected()가있는 경우 다음 타이머 틱 다음 작업에 대한 경과 시간을 재설정해야한다 즉 그 순간부터 발생한다, 외부 이벤트에서 호출 할 수 있다는 것입니다. 그러나, 나는 단지 첫 눈금을 얻고 그 시점부터 타이머는 작동하지 않습니다. Timer 클래스를 사용하는 것에 국한되지 않습니다. 위 시나리오를 해결할 수있는 모든 것이 작동합니다. 나는 postDelayed를 사용하는 것에 대해 다루었지만,이 코드는 서비스에 있으며 UI 스레드를 인식 할 필요가 없습니다.

답변

9

타이머 용으로 별도의 스레드를 사용하는 것은 Android 기기에서 다소 나쁜 습관으로 간주됩니다. 그것은 대부분의 시나리오에서 리소스를 낭비하기 때문입니다.

초 정밀 타이밍 이벤트가 필요하지 않은 경우 Handler 타이머를 사용해야합니다. 이러한 타이머의 예는 여기에서 볼 수 있습니다 : Repeat a task with a time delay?. 이 접근 방식은 활동 및 서비스 모두에서 작동합니다.

또한 기기가 절전 모드로 전환되면 HandlerTimer 기반 타이머가 일시 중지됩니다. 이것이 필요한 것이 아니라면 AlarmManager을 사용하십시오 (단, AlarmManager을 잘못 사용하면 배터리 성능이 저하 될 수 있습니다).

void resetRepeatingTask() { 
    mHandler.removeCallbacks(mBeatDetector); 
    mHandler.postDelayed(mBeatDetector, mInterval);   
} 
+0

핸들러와 AlarmManager를 살펴 보았습니다. 내 작업이 2 초마다 반복되는 것을 고려하면 AlarmManager가 최선의 선택이 아닙니다. 본질적으로 Handler와 Timer는 똑같은 일을 할 것입니다. 그러나 타이머/처리기가 실행되는 동안 내 문제는 "다음 틱"다시 설정할 수 있습니다. –

+0

Yeap, AlarmManager가 너무 무겁습니다. 'Handler'를 재설정하려면'Handler.removeCallbacks()'와'Handler.postDelayed()'를 다시 호출하십시오. 지연이 다시 시작됩니다. – inazaruk

+0

"타이머 재설정"예제로 업데이트되었습니다. – inazaruk

2

허용 된 대답은 (적어도 나를 위해) 작동하지 않습니다 다음 Handler 기반 타이머를 다시 설정하라는


.

간단한 솔루션은 Timer을 사용하여 쉽게 재설정 할 수있는 TimerTask을 트리거합니다. 새로운 TimerTask 당신이 타이머를 재설정 할 때마다 작성해야한다는

Log.d(TAG, "Restarting timer"); 
if (timer != null) { 
    timer.cancel(); 
} 
timer = new Timer(); 
timer.schedule(new TimerTask() { 
    @Override 
    public void run() { 
     Log.d(TAG, "Run the task"); 
    } 
}, 1000); 

주 - 당신은 이전을 다시 사용할 수 없습니다. 상태를 유지하려면 별도의 작업을 실행하기 위해 타이머 작업을 가져와야합니다.

+0

감사합니다. –