Android : Handler ()는 언제 사용해야하며 언제 Thread를 사용해야합니까? 네트워크를 사용하는 논리

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

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



답변

만약 당신이하고있는 것이 “무거운”이라면 당신은 스레드에서 그것을해야합니다. 자체 스레드에서 명시 적으로 시작하지 않으면 기본 (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, 무거운 산술 등)을 할 때마다 스레드를 사용해야합니다.


답변

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

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

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

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


답변

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

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


답변

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

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

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


답변

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

사용하다:

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

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

기사를보십시오


답변

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

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

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

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

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


답변

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

처리기 보내고 프로세스 메시지 수와 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작업이 단일 스레드에서 실행됩니다.

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