Android : Handler ()는 언제 사용해야하며 언제 Thread를 사용해야합니까?


129

장시간 실행되는 작업 이나 네트워크를 사용하는 논리 와 같은 비동기식 으로 실행해야 할 필요가 있거나 어떤 이유로 든 새 스레드를 시작 하고 실행하는 것이 좋습니다. 만들기 처리기를 하고 그것을 실행하는 것은 잘 작동합니다. 차이점이 뭐야? 언제 사용해야합니까? 를 사용하는 것이 아닌 장점은 무엇입니까 ?HandlerThread

추신. -이 질문을 위해 무시합시다 AsyncTask. - Handler().postDelayed유스 케이스는 나에게 분명합니다.이 질문을 위해 즉시 시작해야 할 작업이 필요하다고 가정 해 봅시다.


상황에 따라 직진하고 새 스레드를 사용하십시오. 다음 제안은 AsyncTask이지만 명확하게 원하는 것은 아닙니다. 핸들러는 실행 가능 파일에 지연 또는 다른 유형의 사용자 정의를 추가하려는 경우 주로 사용됩니다.
kabuto178

1
@ kabuto178 잘, 당신이 건너 뛰었다는 언급 할 가치가있는 처리기의 다른 이점이 있습니다. 예를 들어, 별도의 스레드에서 UI 스레드와 상호 작용할 수 있습니다.
tony9099

답변:


168

만약 당신이하고있는 것이 "무거운"이라면 당신은 스레드에서 그것을해야합니다. 자체 스레드에서 명시 적으로 시작하지 않으면 기본 (UI) 스레드에서 실행되어 사용자가 인터페이스를 느리게 응답하거나 느리게 보일 수 있습니다.

흥미롭게도 스레드를 사용할 때 시작하는 작업 스레드와 기본 스레드 간의 통신 수단으로 핸들러를 사용하는 것이 유용합니다.

일반적인 스레드 / 핸들러 상호 작용은 다음과 같습니다.

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            updateUI();
        }else{
            showErrorDialog();
        }
    }
};

Thread t = new Thread() {
    @Override
    public void run(){
        doSomeWork();
        if(succeed){
            //we can't update the UI from here so we'll signal our handler and it will do it for us.
            h.sendEmptyMessage(0);
        }else{
            h.sendEmptyMessage(1);
        }
    }   
};

그러나 일반적으로 집에 가져 가려면 오래 실행되거나 매우 집중적 인 작업 (예 : 네트워크, 파일 IO, 무거운 산술 등)을 할 때마다 스레드를 사용해야합니다.


빠른 답변과 투자 시간 (답장 속도)에 감사드립니다! Handler는 작업자 스레드와 UI 스레드 간의 비 차단 통신을 용이하게하도록 설계 되었습니까?
JRun

3
@JRun 그것은 예 중 하나입니다. 이에 대한 훌륭한 정보 는 java 문서에서 핸들러 설명을 확인하십시오 . 다른 용도를 포함 함 (메시지 및 실행 가능 파일이 향후 특정 시점으로 실행되도록 예약).
FoamyGuy

@FoamyGuy를 잘 설명했다!
tony9099

안녕하십니까 (새보기가로드 된 후) 후에 updateUI()실행되도록 보장 onCreateView됩니까?
Zyoo

1
왜 그렇 message.what()습니까? 그냥 if(msg == 0){아닌가? 정말 고마워! :)
Ruchir Baronia 2017 년

64

핸들러와 스레드는 실제로 두 가지입니다.

장기 실행 작업을 실행하려면 스레드를 작성해야합니다.

핸들러는 2 개의 스레드간에 통신하기에 매우 편리한 객체입니다 (예 : 백그라운드 스레드는 UI를 업데이트해야합니다. 핸들러를 사용하여 백그라운드 스레드에서 UI 스레드로 일부 Runnable을 게시 할 수 있습니다).

따라서 처리기 또는 스레드 중에서 선택할 수 없습니다. 스레드를 사용하여 무거운 작업을 수행하십시오! (백그라운드 스레드가 다른 스레드에서 일부 작업을 트리거하는 경우 핸들러를 사용할 수 있습니다. 대부분의 경우 UI 스레드)


빠른 답변과 투자 시간 (답장 속도)에 감사드립니다!
JRun

28

Handler그리고 Thread다른 두 가지가 있지만, 그들은 서로 모순되지 않는다. a Handler와 a Thread를 동시에 가질 수 있으며 실제로 각각 Handler에서 실행 중이어야합니다 Thread.

자세한 내용은 이 기사를 참조하십시오 .

여기에 이미지 설명을 입력하십시오


19

Handler같은에서 실행 Thread하는 Thread다른 스레드에서 실행됩니다.

동일한 스레드 에서 일반적으로 GUI 요소 또는 이와 유사한 것을 실행해야하는 경우 핸들러를 사용하십시오 .

메인 스레드가 다른 작업을 자유롭게 할 수 있도록하려면 스레드를 사용하십시오 . 시간이 많이 걸리는 모든 작업에 사용하십시오.


6
같은 스레드에서 무언가를 실행하려면 왜 핸들러를 사용해야합니까? mHandler.post (...) 메소드의 목적은 무엇입니까?
Elias

1
이러한 경우, 일정 시간 후에 특정 작업을 실행하거나 X 시간마다 작업을 반복하려는 경우 처리기를 사용할 수 있습니다. 이런 것들을 사용하고 싶지 않다면 옳습니다. 핸들러를 사용할 가치가 없습니다. 처리기가 작성된 스레드에서 처리기가 실행되므로 GUI 작업을 바로 수행 한 다음 UI 스레드에있는 bcoz를 수행 할 수 있습니다.
tony9099

14

핸들러는 백그라운드와 UI 스레드 사이의 가장 좋은 통신 방법입니다. 일반적으로 처리기는 스레드의 메시지 큐와 연결되며 메시지를 보내고 메시지에 실행할 수 있습니다.

사용하다:

스레드 : UI 스레드보다 saperate (Background) 스레드에서 작업을 수행합니다. (UI 스레드 차단을 해제하는 데 도움이 됨)

처리기 UI와 백그라운드 스레드 간의 통신에 사용됩니다.

기사를보십시오


4

새 스레드에서 사용자 인터페이스를 업데이트해야하는 경우 사용자 인터페이스 스레드와 동기화해야합니다.

이를 위해 android.os.Handler 클래스 또는 AsyncTasks 클래스를 사용할 수 있습니다.

핸들러 클래스는 사용자 인터페이스를 업데이트 할 수 있습니다. 핸들러는 Message 또는 Runnable 클래스의 인스턴스를 수신하기위한 메소드를 제공합니다.

스레드는 sendMessage (Message msg) 메소드 또는 sendEmptyMessage () 메소드를 통해 메시지를 게시 할 수 있습니다.

... 스레드 등에 대한 자세한 정보는 여기 (다양한 스레딩 및 동기화 메커니즘에 대한 turorials 포함 및 사용시기)


시간을내어 질문에 답변 해 주셔서 감사합니다. Lars Vogel의 블로그를 좋아합니다. 매우 통찰력이 있고 따르기 쉽습니다. 감사!
JRun

2

스레드가 아닌 처리기를 사용하는 이점 / 이유는 무엇입니까?

처리기 보내고 프로세스 메시지 수와 Runnable스레드의와 관련된 객체 MessageQueue. 각 Handler인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연관됩니다.

새를 만들면 Handler스레드를 만드는 스레드의 스레드 / 메시지 큐에 바인딩됩니다. 이때부터 메시지와 실행 파일을 해당 메시지 큐로 전달하고 메시지 큐에서 나올 때 실행합니다. .

핸들러에는 두 가지 주요 용도가 있습니다.

  1. 메시지 및 Runnables 가 나중에 특정 시점에 실행되도록 예약하려면
  2. 자신과 다른 스레드에서 수행 할 작업 을 큐에 넣습니다 .

자바 스레드를 사용하는 경우 메인 스레드와 동기화, 스레드 취소 등 무언가를 스스로 처리해야합니다.

당신이 사용하지 않는 한이 단일 스레드는 스레드 풀을 만들지 않습니다 ThreadPoolExecutor또는 ExecutorServiceAPI를.

(Blackbelt 답변에 대한 귀하의 의견 에서이 쿼리를 가져 왔습니다)

왜 집행자를 사용하지 않습니까? 처리기를 사용하여 그렇게하고 싶더라도 어떻게해야합니까?

참조 : 스레드 성능 기사

고도의 병렬 분산 작업으로 줄일 수있는 특정 유형의 작업이 있습니다. 작품의 엄청난 양이 (가) 작성하는 패킷, AsyncTask그리고 HandlerThread적절한 클래스하지 않습니다. 단일 스레드 특성은 AsyncTask모든 스레드 풀 작업을 선형 시스템으로 전환합니다. HandlerThread반면에 클래스를 사용하려면 프로그래머가 스레드 그룹 간의로드 밸런싱을 수동으로 관리해야합니다.

ThreadPoolExecutor 는이 과정을보다 쉽게 ​​해주는 도우미 클래스입니다. 이 클래스는 스레드 그룹 작성을 관리하고 우선 순위를 설정하며 스레드간에 작업이 분배되는 방식을 관리합니다. 워크로드가 증가하거나 감소함에 따라 클래스는 더 많은 스레드를 스핀 업 또는 파괴하여 워크로드에 맞 춥니 다.

 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

자세한 내용 은 create-threadpool에 대한 이 개발자 안내서 를 참조하십시오.

Handler여러 개의 Runnable 인스턴스를 실행하는 방법에 대해서는이 게시물을 살펴보십시오 . 이 경우 모든 Runnable작업이 단일 스레드에서 실행됩니다.

안드로이드 : 스레드 토스트


1

HandlerThread큐 메커니즘을 작성하기 위해 함께 사용할 수 있습니다 . Uou를 사용 handler하여Thread Looper


시간을내어 질문에 답변 해 주셔서 감사합니다. 왜 집행자를 사용하지 않습니까? Handler를 사용하여 그렇게하고 싶더라도 어떻게해야합니까?
JRun

집행자는 약간 다릅니다. 그것을 사용하려면 스레드를 확장하고 실행 중에 Looper 클래스의 static.metohd Preparing.를 호출해야합니다. 정적 메소드 루프를 호출하면 큐가 생성되고 handlerbin 순서를 사용하여 요청을 전달하고 결과를 다시 얻을 수 있습니다.
Blackbelt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.