Timertask 또는 핸들러


103

10 초마다 몇 가지 작업을 수행하고 싶고 뷰를 업데이트 할 필요가 없다고 가정 해 보겠습니다.

질문은 다음과 같이 timertask와 함께 타이머를 사용하는 것이 더 낫습니까 (더 효율적이고 효과적이라는 의미입니다).

final Handler handler = new Handler();

TimerTask timertask = new TimerTask() {
    @Override
    public void run() {
        handler.post(new Runnable() {
            public void run() {
               <some task>
            }
        });
    }
};
timer = new Timer();
timer.schedule(timertask, 0, 15000);
}

또는 postdelayed가있는 핸들러

final Handler handler = new Handler(); 
final Runnable r = new Runnable()
{
    public void run() 
    {
        <some task>
    }
};
handler.postDelayed(r, 15000);

또한 어떤 접근 방식을 사용해야하는지, 왜 그중 하나가 다른 접근 방식보다 더 효율적인지 설명해 주시면 감사하겠습니다.


2
TimerTasks의 불규칙한 동작에 대한 많은 게시물을 읽었습니다. 내 조언은 그것들을 피하고 handler / postDelayed 접근 방식을 사용하는 것입니다.
Sound Conception

1
나는 처리기 - postDelay 방법을 선호하는 것 - 당신이 더 많은 컨트롤이 있고 내부에서 일정
미하일

1
여기에 대한 좋은 소스 타이머 대 처리기
CodyF

TimerTask는 백그라운드 작업이므로 UI를 업데이트 할 수 없습니다. 그냥 ... 말
Yousha Aleayoub

1
나를 위해 일했다 .. 감사합니다
jyotsna

답변:


96

Handler보다 낫습니다 TimerTask.

Java TimerTask와 Android Handler모두 백그라운드 스레드에서 지연 및 반복 작업을 예약 할 수 있습니다. 그러나 문헌 은 Android에서 Handlerover TimerTask를 사용 하는 것을 압도적으로 권장합니다 ( here , here , here , here , here , here 참조 ).

TimerTask와 관련하여보고 된 문제 중 일부는 다음과 같습니다.

  • UI 스레드를 업데이트 할 수 없습니다.
  • 메모리 누수
  • 신뢰할 수 없음 (항상 작동하지는 않음)
  • 오래 실행되는 작업은 다음 예약 된 이벤트를 방해 할 수 있습니다.

내가 본 모든 종류의 Android 예제에 대한 최고의 소스는 Codepath 입니다. 다음은 Handler반복되는 작업에 대한 예입니다.

// Create the Handler object (on the main thread by default)
Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnableCode = new Runnable() {
    @Override
    public void run() {
      // Do something here on the main thread
      Log.d("Handlers", "Called on main thread");
      // Repeat this the same runnable code block again another 2 seconds
      handler.postDelayed(runnableCode, 2000);
    }
};
// Start the initial runnable task by posting through the handler
handler.post(runnableCode);

관련


6
@Reek 아니요, GC가 처리해야합니다. 그러나 지연된 실행을 위해 게시 된 실행 가능 파일을 처리해야합니다. 위의 예에서 사용 된 실행 파일은 내부 클래스 인스턴스이므로 포함하는 클래스 (활동 일 수 있음)에 대한 암시 적 참조를 보유합니다. runnable은 컨텍스트가 유효하지 않고 포함 된 클래스 인스턴스를 누출 할 수있는 다음 실행 시간까지 핸들러의 연관된 루퍼의 메시지 큐에 남아 있습니다. mHandler.removeCallbacks(runnableCode)적절한 시간 (예 : onStop()활동) 을 사용하여 이러한 참조를 지울 수 있습니다 .
bitbybit

7
참조를 제시하는 가장 좋은 방법 !!! (여기, 여기, 여기, 여기, 여기, 여기 참조).
iRavi iVooda

ViewModel 내에서 사용하려면 어떻게해야합니까? 거기에 안드로이드를 가지고 있지 않다는 이상이 아닌가?
desgraci

@desgraci, 저는 ViewModel을 사용하지 않았지만 문서 에서 ViewModel이 뷰 계층 구조에 액세스하거나 Activity 또는 Fragment에 대한 참조를 포함해서는 안된다고 만 표시합니다. 일반적으로 "Android 사물"을 사용하는 것을 금지하는 것은 없습니다.
Suragch

오늘부터 이러한 참조는 구식이며 고려할만큼 충분히 유익하지 않습니다. 나열된 네 가지 단점은 코드를 잘못 프로그래밍 한 경우에만 현실입니다. TimerTasks는 주기적으로 백그라운드에서 무언가를 실행하고 일부 조건이 적용되면 결국 UIThread에서 무언가를 실행하려는 경우 여전히 매우 좋은 선택입니다.
David

18

타이머 사용에는 몇 가지 단점이 있습니다.

작업을 실행하기 위해 단일 스레드 만 생성하고 작업을 실행하는 데 너무 오래 걸리면 다른 작업이 어려움을 겪습니다. 작업에서 발생한 예외를 처리하지 않고 스레드가 종료되어 다른 예약 된 작업에 영향을 미치며 실행되지 않습니다.

복사 출처 :

TimerTask vs Thread.sleep vs Handler postDelayed-N 밀리 초마다 함수를 호출하는 것이 가장 정확합니까?


6
원샷 작업은 어떻습니까? 메시지 대기열의 오버 헤드가 없기 때문에 Timer가 더 나은 것 같습니다.
Michael

2
나는 우리가 결코 알지 못할 것 같아요
Denny

6

수락 된 답변의 Kotlin 버전 :

val handler = Handler()

val runnableCode = object : Runnable {
    override fun run() {
       Log.d("Handlers", "Called on main thread")
       handler.postDelayed(this, 2000)
    }
}

handler.post(runnableCode)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.