programing

핸들러 대 비동기 작업 대 스레드

cafebook 2023. 7. 27. 22:18
반응형

핸들러 대 비동기 작업 대 스레드

나는 사이의 차이점에 대해 약간 혼란스러웠습니다.Handlers,AsyncTask그리고.Threads안드로이드로.StackOverflow에서 블로그와 질문을 꽤 많이 읽었습니다.

Handler할 수 입니다.예를 들어 진행률 표시줄 업데이트는 다음을 통해 수행해야 합니다.Handler핸들러를 사용하면 다음과 같은 이점이 있습니다.MessagingQueues메시지를 예약하거나 여러 UI 요소를 업데이트하거나 반복 작업을 수행하려는 경우에 사용할 수 있습니다.

AsyncTask는 합니다사, 실은용, 들합니다그유사사를 합니다.Handler그러나 UI 스레드에서 실행되지 않으므로 데이터 가져오기, 예를 들어 웹 서비스 가져오기에 적합합니다.나중에 UI와 상호 작용할 수 있습니다.

Thread 작용할 수 더 많은 "를 제공할 수 , 은 "사용자 인터페이스", " 인터페이스", "사용자 인터페이스"의 모든 됩니다.AsyncTask.

하지만, 저는 서비스 중에 소켓 연결을 실행하고 싶습니다.는 이을핸스실서에하행야는해지면, 심어지니아나러들레드.AsyncTaskUI 상호 작용은 전혀 필요하지 않습니다.제가 사용하는 성능에 차이가 있습니까?

한편, 문서는 주로 개선되었습니다.

를▁see▁if다,▁we있니▁code▁will습▁source수▁the▁look▁at알▁we소스.AsyncTask그리고.Handler순수하게 Java로 작성되었습니다. (하지만 몇 가지 예외가 있습니다.)하지만 그것은 중요한 포인트가 아닙니다.)

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

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

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

일부 작업에 새 스레드를 사용해야 하는 이유는 무엇입니까?구글에서 검색할 수 있습니다.많은 이유, 예를 들어 무겁고 오래 지속되는 작업을 들어올리는 것.

그럼, 어떤 점이 다른가요?Thread,AsyncTask,그리고.Handler?

AsyncTask그리고.Handler 작내다니 (자바 성됩사용)).Thread), 가 할 수 모든 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .Handler또는AsyncTask우리는 a를 사용하는 것을 달성할 수 있습니다.Thread도 마찬가지야

무엇을 할 수 있습니까?Handler그리고.AsyncTask정말 도움이 될까요?

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

그것이 우리가 사용해야 하는 이유입니다.Handler그리고.AsyncTask이 수업들은 우리를 위해 대부분의 일을 합니다. 우리는 어떤 방법을 무시해야 하는지만 알면 됩니다.

Handler그리고.AsyncTask: 사용AsyncTask호출자 스레드가 UI 스레드인 경우.안드로이드 문서에는 다음과 같은 내용이 있습니다.

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

저는 두 가지 점을 강조하고 싶습니다.

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

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

이 게시물에는 UI 스레드가 무엇인지, 왜 더 쉬운지 등 아직 말하지 않은 것이 많습니다.당신은 각 수업의 배경에 있는 몇 가지 방법을 알고 사용해야 합니다, 당신은 그 이유를 완전히 이해할 수 있을 것입니다.

Android 문서를 읽으면 다음과 같은 내용이 표시됩니다.

처리기를 사용하면 스레드의 MessageQueue와 연결된 Message 및 Runnable 개체를 보내고 처리할 수 있습니다.

이 설명은 처음에는 이상하게 보일 수 있습니다.각 스레드에는 각 메시지 대기열이 있으며(작업을 마치고 잠자리에 드는 것처럼), 스레드는 각 메시지를 가져와서 메시지 대기열이 비울 때까지 수행합니다.그래서, 언제Handler통신합니다. 발신자 스레드에 메시지를 주고 처리를 대기합니다.

복잡해요?그것만은 기억해.Handler호출자 스레드와 안전하게 통신할 수 있습니다.

Vogella 사이트의 Handler, AsyncTask 및 Loaders를 사용한 Android 백그라운드 처리에 대한 튜토리얼에 따르면 다음과 같습니다.

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

AsyncTask합니다.class.class는 기본 스레드와 동기화됩니다.또한 실행 중인 태스크의 진행률 보고도 지원합니다.

그리고Thread 사용할 수 있는 멀티스레딩의 입니다.

Java 스레드를 사용하는 경우 다음 요구 사항을 자체 코드로 처리해야 합니다.

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

그리고 그것에 관해서는.AsyncTaskAndroid Developer's Reference에 따르면 다음과 같습니다.

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

AsyncTask주변의 도우미 클래스가 되도록 설계되었습니다.Thread그리고.Handler일반적인 스레드 프레임워크를 구성하지 않습니다.AsyncTasks는 짧은 작업(최대 몇 초)에 이상적으로 사용해야 합니다.스레드를 장기간 실행해야 하는 경우 실행자, 스레드 풀 실행자 및 FutureTask와 같은 java.util.concurrent 패키지에서 제공하는 다양한 API를 사용하는 것이 좋습니다.

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

구글 검색입니다: 더글러스 슈미트가 안드로이드 동시성과 동기화를 강의합니다.

이것은 유튜브의 첫 번째 강의 영상입니다.

이 모든 것은 CS 282(2013)의 일부입니다. Vanderbilt University의 Android용 시스템 프로그래밍.YouTube 재생 목록입니다.

더글러스 슈미트는 훌륭한 강사인 것 같습니다.

중요:사용을 고려 중인 경우AsyncTask스레드화 문제를 해결하려면 먼저 보다 적절한 프로그래밍 패턴을 확인해야 합니다.개요를 얻기 위한 매우 좋은 자료는 예를 들어 Android용 RxJava 2 학습입니다.

자세히 보니, 그것은 바로 앞으로 나아갑니다.

AsyncTask:

자바 스레드 모델에 대해 아무것도 모르면서 스레드를 사용하는 간단한 방법입니다.AsyncTask에서는 작업자 스레드 및 메인 스레드에 대해 다양한 콜백을 제공합니다.

다음과 같은 소규모 대기 작업에 사용합니다.

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

Handler:

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

처리기를 사용하면 다른 백그라운드 스레드의 UI 스레드와 통신할 수 있습니다.이 기능은 안드로이드에서 다른 스레드가 UI 스레드와 직접 통신할 수 없도록 하기 때문에 유용합니다.처리기는 스레드의 MessageQueue와 연결된 Message 및 Runnable 개체를 보내고 처리할 수 있습니다.각 처리기 인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연결됩니다.새 핸들러가 생성되면 해당 핸들러는 해당 핸들러를 생성하는 스레드의 스레드/메시지 대기열에 바인딩됩니다.

다음 용도에 가장 적합합니다.

  1. 메시지 큐잉을 수행할 수 있습니다.
  2. 메시지 예약.

Thread:

이제 스레드에 대해 이야기할 시간입니다.

스레드는 두 개의 상위 항목입니다.AsyncTask그리고.Handler둘 다 내부적으로 스레드를 사용합니다. 즉, 다음과 같은 스레드 모델을 만들있습니다.AsyncTask그리고.Handler그러나 이를 위해서는 Java의 멀티스레딩 구현에 대한 충분한 지식이 필요합니다.

안 안AsyncTask는 일부 백그라운드 계산을 수행하고 결과를 UI 스레드에 게시하는 데 사용됩니다(선택적 진행률 업데이트 포함).UI에 UI를 사용하면 .Handler또는Thread더 적합해 보입니다.

은 배경을 수 .Thread를 사용하여 합니다.Handlerpost방법.

Android는 표준 Java 스레드를 지원합니다.패키지의 표준 스레드 및 도구를 사용할 수 있습니다. "java.util.concurrent동작을 백그라운드에 배치합니다.유일한 제한 사항은 백그라운드 프로세스에서 UI를 직접 업데이트할 수 없다는 것입니다.

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

핸들러

래스클▁" "HandlerUI를 업데이트할 수 있습니다.핸들은 메시지 수신 및 실행 파일에 대한 방법을 제공합니다.핸들러를 사용하려면 핸들러를 하위 분류하고 재정의해야 합니다.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 스레드에 영향을 주지 않고 장시간 실행되는 백그라운드 작업에 적합합니다.Thread에서는 Thread를 할 수 . java는 UI를 업데이트 할 수 없습니다.

일반 스레드는 Android 아키텍처에서 그다지 유용하지 않기 때문에 스레드를 위한 도우미 클래스가 도입되었습니다.

쿼리에 대한 답변은 스레드화 성능 설명서 페이지에서 찾을 수 있습니다.

처리기:

A Handler및 메지를보처수있리다니습내할고시▁and▁message를 전송 및 할 수 .Runnable스드와관객과 MessageQueue .각각Handler인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연결됩니다.

의 주요 용도는 두 가지입니다.Handler:

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

  2. 자신의 스레드가 아닌 다른 스레드에서 수행할 작업을 대기열에 넣습니다.

비동기 작업:

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

단점:

  1. 기으로모, 앱것푸시다니합을든은을 .AsyncTask개체를 하나의 스레드로 만듭니다.따라서 직렬 방식으로 실행되며, 특히 긴 작업 패킷이 대기열을 차단할 수 있습니다.이러한 이유로 비동기 작업을 사용하여 기간이 5ms 미만인 작업 항목을 처리합니다.

  2. AsyncTask객체는 암시적 참조 문제에 대한 가장 일반적인 위반자이기도 합니다.AsyncTask객체는 명시적인 참조와 관련된 위험도 나타냅니다.

처리기 스레드:

장시간 실행되는 스레드에서 작업 블록을 실행하는 데(5ms 워크로드에 사용해야 하는 AsyncTask와 달리) 보다 전통적인 방식과 해당 워크플로우를 수동으로 관리하는 일부 기능이 필요할 수 있습니다.처리기 스레드는 대기열에서 작업을 가져와 해당 작업에서 작동하는 효과적으로 장시간 실행 스레드입니다.

스레드 풀 실행자:

이 클래스는 스레드 그룹의 생성을 관리하고, 우선 순위를 설정하며, 이러한 스레드 간에 작업이 분산되는 방식을 관리합니다.워크로드가 증가하거나 감소하면 클래스가 회전하거나 더 많은 스레드를 제거하여 워크로드에 맞게 조정합니다.

가 더 단일인 HandlerThread충분하지 않습니다, 당신은 할 수 있습니다.ThreadPoolExecutor

하지만 저는 서비스 중에 소켓 연결을 실행하고 싶습니다.이 작업을 핸들러나 스레드 또는 비동기 작업에서 실행해야 합니까?UI 상호 작용은 전혀 필요하지 않습니다.제가 사용하는 성능에 차이가 있습니까?

없기 할 수 .AsyncTask일반적인 스레드는 그다지 유용하지 않습니다.HandlerThread최선의 선택입니다.소켓 연결을 유지해야 하기 때문에 메인 스레드의 Handler는 전혀 유용하지 않습니다.성을 합니다.HandlerThread그리고 a를 얻습니다.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);

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

Android:실타래로 토스트

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

갱신하다

위의 답변은 무시해주세요!저는 이 질문에 대해 지금보다 안드로이드에 대한 경험이 훨씬 적었던 2011년에 답했습니다.위의 제 답변은 오해의 소지가 있고 잘못된 것으로 간주됩니다.아래에 많은 분들이 저를 수정해주셔서 제가 교훈을 얻어서 거기에 두고 갑니다.

이 스레드에는 훨씬 더 나은 다른 답들이 있지만, 저는 적어도 저에게 더 적절한 답을 줄 것입니다.인 자바를 사용하는 .Thread그러나 잘못하면 프로세서가 많이 소모될 수 있으므로 구현 방법에 주의해야 합니다(가장 주목할 만한 증상은 장치가 뜨거워지는 것일 수 있음).AsyncTasks는 백그라운드에서 실행하려는 대부분의 작업(디스크 I/O, 네트워크 호출, 데이터베이스 호출 등)에 매우 적합합니다. 하만지,AsyncTask사용자가 앱을 닫거나 장치를 대기 상태로 전환한 후에도 계속해야 할 수 있는 특히 긴 프로세스에는 s를 사용해서는 안 됩니다.대부분의 경우 UI 스레드에 속하지 않는 모든 것은 다음과 같이 처리할 수 있습니다.AsyncTask.

AsyncTask백그라운드에서 수행되는 작업을 몇 초 이하로 수행하도록 설계되었습니다(서버에서 파일을 다운로드하거나 파일 IO 작업과 같은 계산 CPU 집약적인 작업에는 권장되지 않습니다).장시간 실행 작업을 실행해야 하는 경우 Java 네이티브 스레드를 사용하는 것이 좋습니다.자바는 당신이 필요로 하는 것을 할 수 있는 다양한 스레드 관련 클래스를 제공합니다.HandlerUI 스레드를 업데이트합니다.

public class RequestHandler {

    public String sendPostRequest(String requestURL,
                                  HashMap<String, String> postDataParams) {

        URL url;

        StringBuilder sb = new StringBuilder();
        try {
            url = new URL(requestURL);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(15000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);


            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                sb = new StringBuilder();
                String response;
                while ((response = br.readLine()) != null){
                    sb.append(response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }

}

요구 사항에 따라 어떤 것을 선택할지에 따라 다릅니다.

핸들러는 주로 다른 스레드에서 주 스레드로 전환하는 데 사용되며, 핸들러는 실행 가능한 작업을 대기열에 게시하는 루퍼에 연결됩니다.따라서 이미 다른 스레드에 있고 메인 스레드로 전환한 경우 비동기 작업이나 다른 스레드 대신 핸들이 필요합니다.

루퍼가 아닌 주 스레드가 아닌 다른 스레드에서 생성된 핸들이 스레드를 생성할 때 오류를 표시하지 않으면 해당 스레드를 로퍼로 만들어야 합니다.

AsyncTask는 백그라운드 스레드에서 실행되는 코드를 몇 초 동안 실행하고 메인 스레드 ** *AsyncTask 제한 사항 1에 결과를 제공하는 데 사용됩니다.비동기 작업은 활동 수명 주기에 연결되지 않으며 활동이 파괴되더라도 계속 실행되는 반면 로더에는 이러한 제한이 없습니다. 2.모든 비동기 작업은 실행을 위해 동일한 백그라운드 스레드를 공유하며 이는 앱 성능에도 영향을 미칩니다.

스레드는 앱에서 백그라운드 작업에도 사용되지만 메인 스레드에 대한 콜백이 없습니다.요구 사항이 하나의 스레드 대신 일부 스레드에 적합하고 여러 번 작업을 제공해야 하는 경우 스레드 풀 실행자가 더 나은 옵션입니다.예: 글라이드와 같은 여러 URL에서 이미지 로드 요구 사항.

예를 들어 여기 질문에 답하겠습니다 :) - MyImageSearch [메인 활동 화면의 이미지 참조 - 편집 텍스트 / 검색 버튼 / 그리드 보기]

MyImageSearch

MyImageSearch 설명 - 사용자가 편집 텍스트 필드에 세부 정보를 입력하고 검색 버튼을 클릭하면, Flickr에서 제공하는 웹 서비스를 통해 인터넷에서 이미지를 검색합니다(키/비밀 토큰을 얻으려면 등록만 하면 됩니다). 검색을 위해 개별 이미지의 URL을 포함하는 응답으로 HTTP 요청 및 GET JSON 데이터를 다시 보냅니다. 그러면 그리드 보기를 로드하는 데 사용할 수 있습니다.

My Implementation - 주요 활동에서 HTTP Request를 DoInBackGround Method로 전송하는 AsyncTask를 확장하는 내부 클래스를 정의하고 JSON Response를 가져오고 FlickRadapter(기본 어댑터 확장)를 통해 그리드 보기를 업데이트하는 사용할 FlickrItems의 로컬 배열 목록을 업데이트하고 어댑터를 호출합니다.온포스트의 변경된 데이터 집합 알림()비동기 작업을 실행하여 그리드 보기를 다시 로드합니다. 여기서 HTTP 요청은 내가 비동기 작업을 통해 수행했기 때문에 차단 호출입니다. 또한 어댑터에 항목을 캐시하여 성능을 향상시키거나 SDCard에 저장할 수 있습니다. Flickr Adapter에서 부풀릴 그리드에는 진행률 표시줄과 이미지 보기가 구현에 포함되어 있습니다. 아래에 제가 사용한 mainActivity의 코드가 있습니다.

질문에 대한 지금 답변 - 개별 이미지를 가져오기 위한 JSON 데이터가 있으면 처리기, 스레드 또는 비동기 작업을 통해 이미지를 백그라운드로 가져오는 논리를 구현할 수 있습니다.다운로드한 이미지는 UI/메인 스레드에 표시되어야 하므로 스레드가 컨텍스트에 액세스할 수 없기 때문에 그대로 사용할 수 없습니다.Flickr 어댑터에서 제가 생각할 수 있는 선택 사항은 다음과 같습니다.

  • 선택 1: 루퍼 만들기스레드 [스레드 확장] - 이 스레드를 계속 열어두고 하나의 스레드에서 이미지를 순차적으로 다운로드합니다 [looper.loop()].
  • 선택 2: 스레드 풀을 사용하여 myImageView에 대한 참조가 포함된 실행 파일을 myHandler를 통해 게시하지만 그리드 보기의 보기가 재활용되므로 인덱스 4의 이미지가 인덱스 9에 표시되는 문제가 다시 발생할 수 있습니다 [다운로드에 시간이 더 걸릴 수 있음].
  • 선택 3 [사용했습니다]:스레드 풀을 사용하여 ImageView의 인덱스 및 ImageView 자체와 관련된 데이터가 포함된 메시지를 myHandler로 전송합니다. 따라서 Message()를 처리하는 동안에는 현재의 경우에만 ImageView를 업데이트합니다.인덱스가 다운로드하려는 이미지의 인덱스와 일치합니다.
  • 선택 4: AsyncTask를 사용하여 백그라운드에서 이미지를 다운로드하지만 여기서는 스레드 풀에서 원하는 스레드 수에 액세스할 수 없고 안드로이드 버전에 따라 다르지만 선택 3에서는 사용 중인 장치 구성에 따라 스레드 풀의 크기를 의식적으로 결정할 수 있습니다.

여기 소스 코드:

public class MainActivity extends ActionBarActivity {

    GridView imageGridView;
    ArrayList<FlickrItem> items = new ArrayList<FlickrItem>();
    FlickrAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageGridView = (GridView) findViewById(R.id.gridView1);
        adapter = new FlickrAdapter(this, items);
        imageGridView.setAdapter(adapter);
    }

    // To avoid a memory leak on configuration change making it a inner class
    class FlickrDownloader extends AsyncTask<Void, Void, Void> {



        @Override
        protected Void doInBackground(Void... params) {
            FlickrGetter getter = new FlickrGetter();

            ArrayList<FlickrItem> newItems = getter.fetchItems();

            // clear the existing array
            items.clear();

            // add the new items to the array
            items.addAll(newItems);

            // is this correct ? - Wrong rebuilding the list view and should not be done in background
            //adapter.notifyDataSetChanged();

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            adapter.notifyDataSetChanged();
        }

    }

    public void search(View view) {
        // get the flickr data
        FlickrDownloader downloader = new FlickrDownloader();
        downloader.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

저는 제 답변이 좀 더 자세한 내용을 이해하는 데 도움이 되기를 바랍니다.

앱을 시작하면 코드를 실행하는 프로세스가 생성됩니다.컴퓨팅 리소스를 효율적으로 사용하기 위해 프로세스 내에서 스레드를 시작하여 한 번에 여러 태스크를 실행할 수 있습니다.따라서 스레드를 사용하면 유휴 시간 없이 CPU를 효율적으로 활용하여 효율적인 앱을 구축할 수 있습니다.

Android에서 모든 구성 요소는 메인 스레드라는 단일에서 실행됩니다.Android 시스템은 작업을 대기열에 넣고 메인 스레드에서 하나씩 실행합니다.장시간 실행 중인 작업이 실행되면 앱이 응답하지 않습니다.

이를 방지하기 위해 작업자 스레드를 생성하고 백그라운드 또는 장시간 실행되는 태스크를 실행할 수 있습니다.

핸들러

Android는 단일 스레드 모델을 사용하기 때문에 UI 구성 요소는 비 스레드 안전하게 생성됩니다. 즉, 생성된 스레드만 액세스해야 합니다. 즉, UI 구성 요소는 메인 스레드에서만 업데이트되어야 합니다.UI 구성 요소는 기본 스레드에서 실행되므로 작업자 스레드에서 실행되는 작업은 UI 구성 요소를 수정할 수 없습니다.여기서 핸들러가 등장합니다.Looper의 도움을 받는 처리기는 새 스레드 또는 기존 스레드에 연결하고 연결된 스레드에 포함된 코드를 실행할 수 있습니다.

처리기를 사용하면 스레드 간 통신이 가능합니다.핸들러를 사용하면 백그라운드 스레드가 결과를 전송할 수 있고 메인 스레드에 연결된 핸들러가 메인 스레드의 UI 구성 요소를 업데이트할 수 있습니다.

비동기 작업

Android에서 제공하는 AsyncTask는 스레드와 핸들러를 모두 사용하여 백그라운드에서 간단한 작업을 실행하고 백그라운드 스레드에서 메인 스레드로 결과를 쉽게 업데이트할 수 있습니다.

예를 들어 안드로이드 스레드, 핸들러, 비동기 작업스레드 풀을 참조하십시오.

Handler스레드 간의 통신 매체입니다.에서는 주로 핸들러를 통해 하는 데 됩니다.

AsyncTask백그라운드 스레드에서 장시간 실행 중인 응용 프로그램을 수행하는 데 사용됩니다. 포 함 포함AsyncTask백그라운드 스레드에서 작업을 수행하고 응용 프로그램의 메인 스레드에서 결과를 얻을 수 있습니다.

Thread는 동시성과 최대 CPU 활용률을 달성하기 위한 경량 프로세스입니다.하여 앱의 하지 않는 할 수 .

언급URL : https://stackoverflow.com/questions/6964011/handler-vs-asynctask-vs-thread

반응형