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.