처리기 대 AsyncTask


128

처리기보다 AsyncTask를 선택할 때 혼란 스럽습니다. UI를 업데이트하는 n 초마다 실행하려는 코드가 있다고 가정 해보십시오. 왜 다른 것을 선택해야합니까?


1
이것은 AsyncTaskLoaders에서 더 복잡해졌습니다. 자세한 내용은 stackoverflow.com/q/7120813/969325 를 참조하십시오 .
Warpzit

답변:


75

IMO, AsyncTask는 낮은 수준의 세부 정보 (스레드, 메시지 루프 등)에 대해 너무 걱정하지 않고 Android 앱에서 백그라운드 처리를 편리하고 사용하기 쉬운 방법으로 제공하기 위해 작성되었습니다. 작업을 예약하고 필요할 때마다 UI를 쉽게 업데이트 할 수있는 콜백 메소드를 제공합니다.

그러나 AsyncTask를 사용할 때 개발자가 제한 사항을 제출하면 클래스 작성자가 결정한 디자인 결정으로 인해 결과가 나타납니다. 예를 들어, 최근 AsyncTasks를 사용하여 예약 할 수있는 작업 수에 제한이 있음을 발견했습니다.

핸들러는 둘 중 더 투명하며 아마도 더 많은 자유를 줄 것입니다. 따라서 더 많은 것을 제어하려면 Handler를 선택하십시오. 그렇지 않으면 AsynTask가 정상적으로 작동합니다.


맞습니다. 프로젝트의 모든 백그라운드 작업에 AsyncTasks를 사용하고있었습니다. 어느 시점에서 나는 최대 작업 한도에 도달하기 시작했기 때문에 내 작업은 다른 작업이 완료된 후에 시작됩니다. 결국 비동기 작업 사용을 중지하고 해당 제한에 도달하지 않도록 모든 구조를 변경해야했습니다.
tbraun

5
Honeycomb부터는 AsyncTasks하나의 스레드에서 실행되므로 더 이상 병렬 처리가 없습니다. 병렬 Executor구현 에서 여전히 실행할 수 있습니다 .
MrSnowflake

63

내 경험 법칙은 다음과 같습니다.

  • 목록에 표시 할 데이터를 다운로드하는 등 UI와 관련하여 격리 된 작업을 수행하는 경우 계속 진행하십시오 AsyncTask.

  • 다운로드시 표시되는 여러 이미지 ImageViews다운로드 (예 : 다운로드 썸네일 다운로드)와 같이 여러 번 반복되는 작업을 수행 하는 경우 작업 대기열을로 사용하십시오 Handler.


핸들러는 API 레벨 1에 있고 API 레벨 3에있는 ASYNCTASK에 있습니다. 어떤 비용으로 더 이상 사용되지 않습니까? becaz는 이전 버전에서 2.2 및 2.3으로 응용 프로그램을 포팅하는 데 집중하고 있습니다.
yokks

10
조만간 더 이상 사용되지 않습니다. UI가 기본적으로 빌드되므로 핸들러는 더 이상 사용되지 않습니다.
alexanderblom

UI를 표시하기 위해 로더를 사용하여 데이터를로드해서는 안됩니까?
nbarraille

19

주로 다음과 같은 이유로 AsyncTask를 사용하지 마십시오.

  • 시스템에 의해 설정된 ThreadPool 기본 및 최대 크기가 있으므로 AsyncTask가 실행되도록 보장되지 않으며 너무 많은 asynctask를 작성하면 결국 파괴됩니다.

  • 활동 수명주기에 따라 AsyncTask가 실행 중일 때도 자동으로 종료 될 수 있으며이를 제어 할 수 없습니다

  • onPostExecute와 같이 UI 스레드에서 실행되는 AsyncTask 메소드는 참조하는 활동이 더 이상 표시되지 않거나 방향 변경 후와 같이 다른 레이아웃 상태에있을 때 실행될 수 있습니다.

결론적으로 AsyncTask의 UIThread-linked 메소드를 사용하면 안됩니다. 또한 doInBackground에서 중요하지 않은 작업 만 수행해야합니다. 이 문제에 대한 자세한 내용을 보려면이 스레드를 읽으십시오.

AsyncTask가 실제로 개념적으로 결함이 있습니까? 아니면 뭔가 빠졌습니까?

결론적으로 위에서 언급 한 문제 중 하나가 문제가 될 때 AsyncTask 대신 IntentServices, HandlerThread 또는 ThreadPoolExecutor를 사용하는 것을 선호하십시오. 더 많은 작업이 필요하지만 응용 프로그램이 더 안전합니다.


예, 많은 AsyncTasks 사용을 후회하는 데 많은 시간을 보냈습니다. 그들은 훌륭해 보이지만 ... 많은 문제가 있습니다!
SMBiggs

6
귀하의 포인트에 대해 너무 강력하게 게시하는 것은 유감이지만, 귀하의 열악한 스타일은 안드로이드에 noobies를 영향을 줄 수 없습니다. 하나를 가리 킵니다. 그렇게 많은 스레드가 실행되어서는 안됩니다. 당신이 이것을 만나면 당신의 아키텍처는 foobar입니다. Point 2. How on earth .. 네, 안드로이드의 모든 것은 가비지 컬렉터에게 무료 게임입니다 ... 당신은 엄밀히 과업이 아닌 경우에, 위에서 설명한 것처럼 터무니없는 행동을 보게 될 것입니다. 포인트 3. 무례하지 않은 작업 관리는 초보자 기술입니다. onPause를 호출 할 때 종료하거나 적절하게 분리하여 연결합니다.
StarWind0

1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html 이것은 위의 문제없이 올바르게 작업을 수행하는 방법을 배우기 위해 필요한 모든 것입니다 (수백 개의 작업을 분출하는 것과 같은 일을하지 않는다고 가정)
StarWind0

16

당신은 모든 x 초 계산을 수행하려는 경우, 당신은 아마를 예약해야 Runnable켜짐 Handler(와 postDelayed())과 그 Runnable현재의 UI 스레드에서 시작해야합니다. 다른 스레드에서 시작하려면 HandlerThread를 사용하십시오. AsyncTask는 우리에게는 사용하기 쉽지만 핸들러보다 낫습니다.


7

처리기는 응용 프로그램의 기본 스레드와 연결됩니다. 백그라운드 스레드에서 앱 메인 스레드로 전송 된 메시지 및 실행 파일을 처리하고 예약합니다.

AsyncTask는 시간이 많이 걸리는 작업으로 UI를 차단하지 않고 UI를 업데이트하기 위해 백그라운드 스레드를 처리하는 간단한 방법을 제공합니다.

대답은 백그라운드 스레드에서 UI를 업데이트하는 데 사용할 수 있다는 것입니다. 차이점은 실행 시나리오에 있습니다. 처리기를 사용하여 지연된 메시지를 게시하거나 특정 순서로 MessageQueue에 메시지를 보낼 수 있습니다.

앱 메인 스레드와 백그라운드 스레드간에 매개 변수를 교환 (따라서 UI 업데이트)하려는 경우 AsyncTask를 사용하는 것이 좋습니다.


3
다른 스레드와 관련된 자체 처리기를 만들 수 있습니다.
Aleksejs Mjaliks

핸들러는 반드시 메인 스레드 (UI Thread)에 연결되어 있지는 않습니다. 그것은 인스턴스화 된 스레드에 묶여 있으며이 스레드 메시지 대기열에 도착하는 메시지 또는 Runnable을 처리합니다. 또한이 스레드 메시지 큐에 Message 및 Runnable 객체를 보낼 수 있습니다.
azec-pdx

2

AsyncTask일부 백그라운드 작업이 완료된 후 UI 스레드에서 무언가를 수행한다고 가정합니다. 또한 한 번만 실행할 수 있습니다 (이 후 상태는 FINISHED한 번 더 실행하려고하면 예외가 발생 함). 또한 그것을 사용하는 유연성은별로 없습니다. 예, THREAD_POOL_EXECUTOR병렬 실행에 사용할 수 있지만 노력이 가치가 없을 수 있습니다.

HandlerRunnables 및 메시지 처리를 제외하고는 아무것도 가정하지 않습니다. 또한 원하는 횟수만큼 실행할 수 있습니다 . 어떤 스레드에 연결해야하는지, 다른 처리기와 통신하는 방법을 자유롭게 결정할 수 있습니다 HandlerThread. 따라서 반복 작업에 훨씬 유연하고 적합합니다.

여기서 다른 종류의 Handler예제를 확인 하십시오 .


0

그들은 가장 좋은 면접 질문입니다. AsyncTask -UI 스레드를 오프로드하고 백그라운드에서 작업을 수행하는 데 사용됩니다. 처리기 -안드로이드 선량은 UI와 백그라운드 스레드 사이에 직접적인 통신 방법이 있습니다. 핸들러는 메시지를 보내거나 메시지 큐를 통해 실행할 수 있어야합니다.

따라서 백그라운드에서 작업을 실행해야하는 경우 AsyncTasks가 사용되고 UI와 백그라운드 스레드 간의 통신에 핸들러가 사용됩니다.


0

doInBackground- 기본적으로 다른 스레드에서 작동합니다. onPostExecute -UI 스레드에 결과를 게시하고 내부적으로 메인 스레드의 핸들러로 메시지를 보냅니다. 기본 UI 스레드에는 이미 연결된 루퍼 및 핸들러가 있습니다.

따라서 기본적으로 백그라운드 작업을 수행 해야하는 경우 AsyncTask를 사용하십시오. 그러나 궁극적으로 UI에서 무언가를 업데이트 해야하는 경우 메인 스레드의 핸들러를 사용합니다.

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