처리기 대 AsyncTask 대 스레드 [닫힘]

나는 약간의 차이점에 대해 혼동있어 Handlers, AsyncTaskThreads안드로이드한다. StackOverflow에서 꽤 많은 블로그와 질문을 읽었습니다.

HandlerUI와 통신 할 수있는 백그라운드 스레드입니다. 예를 들어 진행률 표시 줄 업데이트는을 통해 수행해야합니다 Handler. 처리기를 사용하면 MessagingQueues메시지를 예약하거나 여러 UI 요소를 업데이트하거나 작업을 반복하려는 경우 이점이 있습니다.

AsyncTask실제로는 비슷 Handler하지만 UI 스레드에서 실행되지 않으므로 웹 서비스 가져 오기와 같은 데이터 가져 오기에 좋습니다. 나중에 UI와 상호 작용할 수 있습니다.

Thread그러나 UI와 상호 작용할 수 없으며 더 많은 “기본”스레딩을 제공하며의 모든 추상화를 놓치게됩니다 AsyncTask.

그러나 서비스에서 소켓 연결을 실행하고 싶습니다. 이것이 핸들러 또는 스레드에서 실행되어야합니까, 심지어AsyncTask ? UI 상호 작용이 전혀 필요하지 않습니다. 내가 사용하는 성능면에서 차이가 있습니까?

한편, 문서 는 크게 개선되었습니다.



답변

처리기를 사용 하여 Android 백그라운드 처리 에 대한 자습서로서 Vogella 사이트의 AsyncTask 및 로더 는 다음 같이 설명 합니다.

Handler클래스의 스레드에 등록 할 때 사용이 스레드에 데이터를 전송하는 간단한 채널을 제공 할 수있다.

AsyncTask클래스는 백그라운드 프로세스 작성 및 기본 스레드와의 동기화를 캡슐화합니다. 실행중인 작업의 진행률보고도 지원합니다.

a Thread는 기본적으로 개발자가 다음과 같은 단점을 가지고 사용할 수있는 멀티 스레딩의 핵심 요소입니다.

Java 스레드를 사용하는 경우 고유 코드에서 다음 요구 사항을 처리해야합니다.

  • 사용자 인터페이스에 결과를 다시 게시하면 기본 스레드와 동기화
  • 스레드를 취소하기위한 기본값이 없습니다.
  • 기본 스레드 풀링 없음
  • Android에서 구성 변경을 처리하기위한 기본값이 없습니다.

그리고 Android Developer ‘s ReferenceAsyncTask따르면 :

AsyncTaskUI 스레드를 적절하고 쉽게 사용할 수 있습니다. 이 클래스를 사용하면 스레드 및 / 또는 핸들러를 조작하지 않고도 백그라운드 작업을 수행하고 UI 스레드에 결과를 게시 할 수 있습니다.

AsyncTask헬퍼 클래스 주위를 수 있도록 설계 ThreadHandler
및 일반적인 스레딩 프레임 워크를 구성하지 않습니다. AsyncTasks는 짧은 작업 (최대 몇 초)에 이상적으로 사용되어야합니다. 스레드를 장시간 계속 실행해야하는 경우 java.util.concurrent 패키지에서 제공하는 다양한 API (예 : Executor, ThreadPoolExecutor 및 FutureTask.

2015 년 5 월 업데이트 : 이 주제를 다루는 훌륭한 강의 시리즈를 발견했습니다 .

이것은 구글 검색입니다 : Douglas Schmidt 강의 Android 동시성 및 동기화

YouTube 첫 강의 비디오입니다

이 모든의 일부입니다 안드로이드 프로그래밍 시스템 : CS 282 (2013) 으로부터 밴더빌트 대학 . YouTube 재생 목록 은 다음과 같습니다.

Douglas Schmidt는 훌륭한 강사 인 것 같습니다

중요 사항 :AsyncTask 스레딩 문제를 해결하기 위해 사용 하고자 하는 시점에있는 경우 먼저 보다 적절한 프로그래밍 패턴을 확인ReactiveX/RxAndroid 해야합니다 . 개요를 얻는 데 매우 유용한 자료는 예를 들어 Android 용 RxJava 2 학습 입니다.


답변

우리는 소스 코드를 보면, 우리가 볼 수 AsyncTaskHandler 순수 자바로 작성된 것입니다. (그러나 몇 가지 예외가 있습니다. 그러나 중요한 것은 아닙니다.)

AsyncTask또는에 마법이 없습니다 Handler. 이 수업은 개발자로서 우리의 삶을 더 쉽게 만듭니다.

예를 들어, 프로그램 A가 메소드 A ()를 호출하면 메소드 A ()는 프로그램 A와 다른 스레드에서 실행될 수 있습니다. 다음 코드를 통해 쉽게 확인할 수 있습니다.

Thread t = Thread.currentThread();
int id = t.getId();

일부 작업에 새 스레드를 사용해야하는 이유는 무엇입니까? 당신은 그것을 구글 할 수 있습니다. 많은 이유, 예 : 무겁고 오래 지속되는 작업 리프팅

그래서, 차이 무엇인가 Thread, AsyncTask그리고는 Handler?

AsyncTaskHandler자바 (내부적으로는을 사용하여 작성됩니다 Thread우리가 할 수있는 모든 있도록) Handler또는 AsyncTask우리는 사용하여 달성 할 수 Thread도 있습니다.

무엇을 할 수 Handler있고AsyncTask 정말 도움이 필요하십니까?

가장 확실한 이유는 호출자 스레드와 작업자 스레드 간의 통신입니다. ( 호출자 스레드 : 일부 작업을 수행하기 위해 작업자 스레드를 호출하는 스레드입니다 . 호출자 스레드는 반드시 UI 스레드 일 필요는 없습니다). 물론 다른 방식으로 두 스레드간에 통신 할 수 있지만 스레드 안전성으로 인해 많은 단점 (및 위험)이 있습니다.

그래서 우리는 Handlerand를 사용해야합니다 AsyncTask. 이 클래스는 대부분의 작업을 수행하므로 재정의 할 메소드 만 알면됩니다.

의 차이 Handler와는 AsyncTask이다 : 사용 AsyncTask하면 발신자 스레드 A는 UI 스레드 . 이것은 안드로이드 문서가 말하는 것입니다 :

AsyncTask를 사용하면 UI 스레드를 적절하고 쉽게 사용할 수 있습니다. 이 클래스를 사용하면 스레드 및 / 또는 핸들러를 조작하지 않고도 백그라운드 작업을 수행하고 UI 스레드에 결과를 게시 할 수 있습니다.

두 가지 사항을 강조하고 싶습니다.

1) UI 스레드를 쉽게 사용할 수 있습니다 (따라서 호출자 스레드가 UI 스레드 인 경우 사용).

2) 핸들러를 조작 할 필요가 없습니다. (의미 : AsyncTask 대신 Handler를 사용할 수 있지만 AsyncTask가 더 쉬운 옵션입니다).

이 게시물에는 아직 말하지 않은 많은 것들이 있습니다. 예를 들어 UI 스레드가 무엇입니까, 왜 더 쉬운 지. 각 클래스의 배후에있는 메소드를 알고 사용해야하며 그 이유를 완전히 이해할 것입니다.

@ : Android 문서를 읽으면 다음이 표시됩니다.

핸들러를 사용하면 스레드의 MessageQueue와 관련된 Message 및 Runnable 객체를 보내고 처리 할 수 ​​있습니다

이 설명은 처음에는 이상하게 보일 수 있습니다. 우리는 각 스레드가 할일 목록과 같은 각 메시지 큐를 가지고 있고 스레드는 각 메시지를 가져 와서 메시지 큐가 비워 질 때까지 (작업을 마치고 잠자리에 든 것처럼) 수행합니다. 그렇게 할 때Handler 통신 호출자 스레드에 메시지를 제공하고 처리를 기다립니다.

복잡한? Handler호출자 스레드와 안전하게 통신 할 수 있다는 것을 기억하십시오 .


답변

심층적으로 살펴본 후에는 간단합니다.

AsyncTask:

자바 스레드 모델에 대해 전혀 몰라도 스레드를 사용하는 간단한 방법 입니다.
AsyncTask워커 스레드와 메인 스레드에 각각 다양한 콜백을 제공합니다.

다음과 같은 작은 대기 작업에 사용하십시오.

  1. 웹 서비스에서 일부 데이터를 가져 와서 레이아웃 위에 표시합니다.
  2. 데이터베이스 쿼리.
  3. 실행중인 작업이 절대 중첩되지 않는다는 것을 알고있을 때.

Handler:

Android에 응용 프로그램을 설치하면 MAIN UI Thread라는 해당 응용 프로그램에 대한 스레드가 생성됩니다. 모든 활동은 해당 스레드 내에서 실행됩니다. Android 단일 스레드 모델 규칙에 따라 해당 활동 내에 정의 된 다른 스레드의 UI 요소 (비트 맵, 텍스트보기 등)에 직접 액세스 할 수 없습니다.

핸들러를 사용하면 다른 백그라운드 스레드에서 UI 스레드와 다시 통신 할 수 있습니다. 이것은 안드로이드가 다른 스레드가 UI 스레드와 직접 통신하는 것을 허용하지 않으므로 안드로이드에서 유용합니다. 처리기는 스레드의 MessageQueue와 관련된 Message 및 Runnable 객체를 보내고 처리 할 수 ​​있습니다. 각 핸들러 인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연관됩니다. 새 핸들러가 작성되면이를 작성중인 스레드의 스레드 / 메시지 큐에 바인드됩니다.

다음에 가장 적합합니다.

  1. 메시지 큐잉을 할 수 있습니다.
  2. 메시지 스케줄링.

Thread:

이제 스레드에 대해 이야기 할 차례입니다.

스레드는 AsyncTask및 의 부모입니다 Handler. 둘 다 내부적으로 스레드를 사용 하므로 and와 같은 자체 스레드 모델을 만들 수 있지만 Java의 다중 스레드 구현에 대한 지식이 필요합니다 .AsyncTaskHandler


답변

AsyncTask몇 가지 배경 계산을하고 (옵션 진행 업데이트) UI 스레드에 결과를 게시하는 데 사용됩니다. UI에 관심이 없으므로 a Handler또는Thread 더 적절한 것으로 보입니다.

의 메소드를 Thread사용하여 백그라운드를 생성하고 메인 스레드로 메시지를 다시 전달할 수 있습니다 .Handlerpost


답변

안드로이드는 표준 자바 스레드를 지원합니다 . 패키지 ” java.util.concurrent” 의 표준 스레드 및 도구를 사용하여 작업을 백그라운드로 수행 할 수 있습니다. 유일한 제한은 백그라운드 프로세스에서 UI를 직접 업데이트 할 수 없다는 것입니다.

백그라운드 작업에서 UI를 업데이트해야하는 경우 일부 Android 특정 클래스를 사용해야합니다. 당신은 클래스 “를 사용할 수 있습니다 android.os.Handler“이 또는 클래스 ” AsyncTask

매니저

Handler” 클래스 는 UI를 업데이트 할 수 있습니다. 핸들은 메시지 수신 및 실행 가능 메소드를 제공합니다. 핸들러를 사용하려면 서브 클래스 handleMessage()를 처리하고 메시지를 처리하도록 대체 해야합니다. 처리하려면 Runable다음 방법을 사용할 수 있습니다 post();. 활동에는 핸들러 인스턴스가 하나만 필요합니다.

당신은 방법을 통해 메시지를 게시 할 수 스레드 sendMessage(Message msg)sendEmptyMessage.

비동기 작업

당신이있는 경우 Activity다운로드 콘텐츠에 대한 어떤 요구를하거나 수행 백그라운드에서 수행 할 수있는 작업은 AsyncTask당신이 반응하는 사용자 인터페이스를 유지하고 사용자에게 그 작업에 대한 진행 상황을 게시 할 수 있습니다.

자세한 내용은 다음 링크를 참조하십시오.

http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/

http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask


답변

Thread:

ThreadUI 스레드에 영향을주지 않으면 서 장기간 실행되는 백그라운드 작업에 새로운 기능 을 사용할 수 있습니다 . Java Thread에서는 UI Thread를 업데이트 할 수 없습니다.

일반 스레드 는 Android 아키텍처에별로 유용하지 않으므로 스레딩을위한 도우미 클래스가 도입되었습니다.

스레딩 성능 문서 페이지 에서 쿼리에 대한 답변을 찾을 수 있습니다 .

처리기 :

A를 Handler사용하면 메시지 및 Runnable스레드와 관련된 객체 를 보내고 처리 할 수 ​​있습니다 MessageQueue. 각 Handler인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연관됩니다.

에 대한 두 가지 주요 용도가 있습니다 Handler.

  1. 메시지 및 실행 가능 파일이 미래의 특정 시점으로 실행되도록 예약합니다.

  2. 자신과 다른 스레드에서 수행 할 작업을 큐에 넣습니다.

AsyncTask :

AsyncTaskUI 스레드를 적절하고 쉽게 사용할 수 있습니다. 이 클래스를 사용하면 스레드 및 / 또는 핸들러를 조작하지 않고도 백그라운드 작업을 수행하고 UI 스레드에 결과를 게시 할 수 있습니다.

단점 :

  1. 기본적으로 앱은 AsyncTask생성 된 모든 개체를 단일 스레드로 푸시합니다 . 따라서 그것들은 직렬 방식으로 실행되며, 메인 스레드와 마찬가지로 특히 긴 작업 패킷이 대기열을 차단할 수 있습니다. 이러한 이유로 AsyncTask를 사용하여 5ms 보다 짧은 작업 항목을 처리하십시오 .

  2. AsyncTask또한 객체는 암시 적 참조 문제의 가장 일반적인 위반자입니다. AsyncTask개체는 명시 적 참조와 관련된 위험도 나타냅니다.

HandlerThread :

장기 실행 스레드 ( 5ms 워크로드에 사용해야하는 AsyncTask와 달리) 에서 작업 블록을 실행하는 전통적인 접근 방식 과 해당 워크 플로우를 수동으로 관리하는 기능 이 필요할 수 있습니다. 핸들러 스레드는 사실상 큐에서 작업을 가져 와서 작동하는 장기 실행 스레드입니다.

ThreadPoolExecutor :

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

작업량이 많고 단일 HandlerThread이 충분하지 않은 경우ThreadPoolExecutor

그러나 서비스에서 소켓 연결을 실행하고 싶습니다. 이것은 핸들러 또는 스레드 또는 AsyncTask에서 실행되어야합니까? UI 상호 작용이 전혀 필요하지 않습니다. 내가 사용하는 성능면에서 차이가 있습니까?

UI 상호 작용이 필요하지 않으므로을 (를) 방문하지 않아도됩니다 AsyncTask. 일반 스레드는별로 유용하지 않으므로 HandlerThread최상의 옵션입니다. 소켓 연결을 유지해야하기 때문에 메인 스레드의 핸들러는 전혀 유용하지 않습니다. 를 작성 HandlerThread하고 얻을 Handler의 루퍼에서 HandlerThread.

 HandlerThread handlerThread = new HandlerThread("SocketOperation");
 handlerThread.start();
 Handler requestHandler = new Handler(handlerThread.getLooper());
 requestHandler.post(myRunnable); // where myRunnable is your Runnable object. 

UI 스레드와 다시 통신하려면 하나 이상의 핸들러를 사용하여 응답을 처리 할 수 ​​있습니다.

final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Foreground task is completed:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

Runnable추가 할 수 있습니다

responseHandler.sendMessage(msg);

구현에 대한 자세한 내용은 다음을 참조하십시오.

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


답변

제 생각에 스레드는 소켓 연결을 수행하는 가장 효율적인 방법은 아니지만 스레드 실행 측면에서 가장 기능을 제공합니다. 경험상 스레드를 오랫동안 실행하면 장치가 매우 뜨겁고 리소스를 많이 사용하게됩니다. 간단한 while(true)것 조차도 몇 분 안에 전화를 데울 것입니다. UI 상호 작용이 중요하지 않다고 말하면 AsyncTask장기 프로세스를 위해 설계되었으므로 좋을 것 입니다. 이것은 단지 내 의견입니다.

최신 정보

위의 답변을 무시하십시오! 나는 지금보다 안드로이드에서 경험이 훨씬 적었던 2011 년 에이 질문에 대답했습니다. 위의 답변은 오도의 소지가 있으며 잘못된 것으로 간주됩니다. 많은 사람들이 아래에서 저를 시정하는 것에 대해 댓글을 달았으므로 수업을 배웠습니다.

이 스레드에는 다른 더 나은 답변이 있지만 적어도 더 적절한 답변을 드리겠습니다. 일반적인 Java를 사용하는 데 아무런 문제가 없습니다 Thread. 그러나 잘못 구현하는 경우 프로세서를 많이 사용하기 때문에 구현 방법에주의해야합니다 (가장 주목할만한 증상은 장치가 가열 될 수 있음). AsyncTask이는 백그라운드에서 실행하려는 대부분의 작업에 매우 이상적입니다 (일반적인 예는 디스크 I / O, 네트워크 호출 및 데이터베이스 호출입니다). 그러나 AsyncTask사용자가 앱을 닫거나 장치를 대기 상태로 전환 한 후에 계속해야하는 특히 긴 프로세스 에는 s를 사용해서는 안됩니다. 대부분의 경우 UI 스레드에 속하지 않는 모든 항목은에서 처리 할 수 ​​있습니다 AsyncTask.


답글 남기기