396

とAndroidの違いについて少し混乱しましたHandlers。私はここStackOverflowでかなりの数のブログと質問を読みました。AsyncTaskThreads

HandlerUIとの通信を提供するバックグラウンドスレッドです。たとえば、プログレスバーの更新は、を介して実行する必要がありますHandler。ハンドラーを使用すると、の利点がありMessagingQueuesます。したがって、メッセージをスケジュールしたり、複数のUI要素を更新したり、タスクを繰り返したりする場合に役立ちます。

AsyncTask似ていますが、実際にはを利用しますHandlerが、UIスレッドでは実行されないため、データのフェッチ、たとえばWebサービスのフェッチに適しています。後でUIを操作できます。

Threadただし、UIと対話できず、より「基本的な」スレッドを提供すると、のすべての抽象化を見逃してしまいますAsyncTask

ただし、ソケット接続を稼働させたいのですが。これはハンドラーまたはスレッドで実行する必要がありAsyncTaskますか?UIの操作はまったく必要ありません。使用するパフォーマンスに違いはありますか?

その間、ドキュメントは大幅に改善されました。

4

13 に答える 13

357

ソースコードを見るAsyncTaskと、Handler純粋にJavaで書かれていることがわかります。(ただし、いくつかの例外があります。ただし、それは重要なポイントではありません)

したがって、AsyncTaskまたはには魔法はありませんHandler。これらのクラスは、開発者としての私たちの生活を楽にします。

例:プログラムAがメソッドA()を呼び出す場合、メソッドA()はプログラムAとは別のスレッドで実行できます。次のコードで簡単に確認できます。

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

一部のタスクに新しいスレッドを使用する必要があるのはなぜですか?あなたはそれをグーグルすることができます。多くの多くの理由、例えば:重く、長時間の作業を持ち上げる。

ThreadではAsyncTask、、、、の違いは何Handlerですか?

AsyncTaskHandlerJavaで書かれているので(内部的にはを使用します)、またはでThreadできることはすべて、を使用して達成することもできます。HandlerAsyncTaskThread

何が本当に役立つHandlerのでしょうか?AsyncTask

最も明白な理由は、呼び出し元スレッドとワーカースレッド間の通信です。(呼び出し元スレッド:いくつかのタスクを実行するためにワーカースレッドを呼び出すスレッド。呼び出し元スレッドは必ずしもUIスレッドである必要はありません)。もちろん、他の方法で2つのスレッド間で通信することもできますが、スレッドの安全性のために多くの欠点(および危険)があります。

そのため、とを使用する必要がHandlerありAsyncTaskます。これらのクラスは私たちのためにほとんどの作業を行います。オーバーライドするメソッドを知る必要があるだけです。

Handlerとの違いは次のとおりです。呼び出し元スレッドUIスレッドの場合にAsyncTask使用します。これはAndroidドキュメントが言っていることです:AsyncTask

AsyncTaskを使用すると、UIスレッドを適切かつ簡単に使用できます。このクラスを使用すると、スレッドやハンドラーを操作しなくても、バックグラウンド操作を実行してUIスレッドで結果を公開できます。

2つのポイントを強調したいと思います。

1)UIスレッドの使いやすさ(したがって、呼び出し元のスレッドがUIスレッドの場合に使用します)。

2)ハンドラーを操作する必要はありません。(意味:AsyncTaskの代わりにHandlerを使用できますが、AsyncTaskの方が簡単なオプションです)。

この投稿には、まだ言っていないことがたくさんあります。たとえば、UIスレッドとは何か、なぜそれが簡単なのかなどです。各クラスの背後にあるいくつかのメソッドを知ってそれを使用する必要があります。その理由を完全に理解できます。

@:Androidドキュメントを読むと、次のように表示されます。

ハンドラーを使用すると、スレッドのMessageQueueに関連付けられたMessageオブジェクトとRunnableオブジェクトを送信および処理できます。

この説明は、最初は奇妙に思えるかもしれません。各スレッドには(やることリストのように)各メッセージキューがあることを理解するだけでよく、スレッドは各メッセージを受け取り、メッセージキューが空になるまでそれを実行します(作業を終えて就寝するのと同じように)。したがって、Handler通信するときは、呼び出し元のスレッドにメッセージを送信するだけで、処理を待機します。

複雑?Handler発信者スレッドと安全に通信できることを覚えておいてください。

于 2012-03-21T08:19:25.213 に答える
61

ハンドラーを使用したAndroidバックグラウンド処理のチュートリアルとして、VogellaサイトのAsyncTaskとLoadersは次のように述べています。

このHandlerクラスはスレッドへの登録に使用でき、このスレッドにデータを送信するための単純なチャネルを提供します。

このAsyncTaskクラスは、バックグラウンドプロセスの作成とメインスレッドとの同期をカプセル化します。また、実行中のタスクの進行状況のレポートもサポートします。

そして、aThreadは基本的にマルチスレッドのコア要素であり、開発者は次の欠点を持って使用できます。

Javaスレッドを使用する場合は、独自のコードで次の要件を処理する必要があります。

  • 結果をユーザーインターフェイスにポストバックする場合のメインスレッドとの同期
  • スレッドをキャンセルするためのデフォルトはありません
  • デフォルトのスレッドプールはありません
  • Androidで構成変更を処理するためのデフォルトはありません

そしてAsyncTaskAndroid Developer's Referenceにあるように、については次のようになります。

AsyncTaskUIスレッドを適切かつ簡単に使用できるようにします。このクラスを使用すると、スレッドやハンドラーを操作しなくても、バックグラウンド操作を実行してUIスレッドで結果を公開できます。

AsyncTaskはヘルパークラスとして設計されておりThreadHandler 一般的なスレッドフレームワークを構成していません。AsyncTasksは、理想的には短い操作(最大で数秒)に使用する必要があります。スレッドを長期間実行し続ける必要がある場合は、java.util.concurrentパッケージによって提供されるさまざまなAPIを使用することを強くお勧めします。 Executor、ThreadPoolExecutorおよびFutureTask。

2015年5月の更新:このトピックをカバーする優れた一連の講義を見つけました。

これはGoogle検索です:ダグラスシュミット講義アンドロイド同時実行と同期

これはYouTubeでの最初の講義のビデオです

これはすべて、 CS 282(2013):ヴァンダービルト大学のAndroid向けシステムプログラミングの一部です。これがYouTubeプレイリストです

ダグラス・シュミットは優秀な講師のようです

重要:AsyncTaskスレッドの問題を解決するために使用することを検討している場合は、最初に、おそらくより適切なプログラミングパターンを確認する必要があります。ReactiveX/RxAndroid概要を理解するための非常に優れたリソースは、例としてAndroid用のRxJava2を学ぶことです

于 2015-04-15T16:18:55.973 に答える
56

深く調べた後、それは簡単です。

AsyncTask

これは、Javaスレッドモデルについて何も知らなくてもスレッドを使用する簡単な方法です。 AsyncTaskワーカースレッドとメインスレッドにそれぞれ対応するさまざまなコールバックを提供します。

次のような小さな待機操作に使用します。

  1. Webサービスから一部のデータを取得し、レイアウト上に表示します。
  2. データベースクエリ。
  3. 実行中の操作がネストされることは決してないことに気付いたとき。

Handler

Androidにアプリケーションをインストールすると、そのアプリケーション用のMAINUIThreadというスレッドが作成されます。すべてのアクティビティはそのスレッド内で実行されます。androidシングルスレッドモデルルールにより、そのアクティビティ内で定義された別のスレッドのUI要素(ビットマップ、テキストビューなど)に直接アクセスすることはできません。

ハンドラーを使用すると、他のバックグラウンドスレッドからUIスレッドと通信できます。これは、Androidでは他のスレッドがUIスレッドと直接通信することを許可しないため、Androidで役立ちます。ハンドラーは、スレッドのMessageQueueに関連付けられたMessageオブジェクトとRunnableオブジェクトを送信および処理できます。各Handlerインスタンスは、単一のスレッドとそのスレッドのメッセージキューに関連付けられています。新しいハンドラーが作成されると、それを作成しているスレッドのスレッド/メッセージキューにバインドされます。

次の場合に最適です。

  1. メッセージキューを作成できます。
  2. メッセージのスケジューリング。

Thread

次に、スレッドについて説明します。

スレッドはとの両方の親AsyncTaskですHandler。どちらも内部でスレッドを使用します。つまり、やのような独自のスレッドモデルを作成することもできますが、それにはJavaのマルチスレッド実装に関する十分な知識が必要です。AsyncTaskHandler

于 2014-05-09T07:39:27.510 に答える
22

AnAsyncTaskは、バックグラウンド計算を実行し、結果をUIスレッドに公開するために使用されます(オプションの進行状況の更新を使用)。UIに関心がないので、HandlerまたはThreadがより適切であるように思われます。

のメソッドを使用して、バックグラウンドを生成し、Threadメッセージをメインスレッドに戻す ことができます。Handlerpost

于 2011-08-06T00:57:17.113 に答える
9

スレッド

Androidは標準のJavaスレッドをサポートしています。パッケージ「<code>java.util.concurrent」の標準スレッドとツールを使用して、アクションをバックグラウンドに置くことができます。唯一の制限は、バックグラウンドプロセスからUIを直接更新できないことです。

バックグラウンドタスクからUIを更新する必要がある場合は、Android固有のクラスを使用する必要があります。これにはクラス「<code>android.os.Handler」またはクラス「<code>AsyncTask」を使用できます</p>

ハンドラ

クラス「<code>Handler」はUIを更新できます。ハンドルは、メッセージを受信するためのメソッドとランナブルを提供するためのメソッドを提供します。ハンドラーを使用するには、ハンドラーをサブクラス化し、handleMessage()メッセージを処理するためにオーバーライドする必要があります。を処理Runableするには、メソッドを使用できpost();ます。アクティビティに必要なハンドラーのインスタンスは1つだけです。

スレッドは、メソッドsendMessage(Message msg)またはを介してメッセージを投稿できますsendEmptyMessage

AsyncTask

Activityコンテンツをダウンロードしたり、バックグラウンドで実行できる操作を実行したりする必要がある場合はAsyncTask、応答性の高いユーザーインターフェイスを維持し、それらの操作の進行状況をユーザーに公開できます。

詳細については、これらのリンクをご覧ください。

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

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

于 2014-03-24T11:03:10.973 に答える
8

Thread

UIスレッドに影響を与えることなく、新しいThreadバックグラウンドタスクを長時間実行するために使用できます。Javaスレッドからは、UIスレッドを更新できません。

通常のスレッドはAndroidアーキテクチャではあまり役に立たないため、スレッド用のヘルパークラスが導入されました。

質問に対する回答は、スレッドパフォーマンスのドキュメントページにあります。

ハンドラー

Aを使用すると、スレッドに関連付けられたHandlerメッセージとオブジェクトを送信および処理できます。各インスタンスは、単一のスレッドとそのスレッドのメッセージキューに関連付けられています。RunnableMessageQueueHandler

の主な用途は2つありますHandler

  1. 将来のある時点で実行されるメッセージとランナブルをスケジュールするため。

  2. 自分のスレッドとは異なるスレッドで実行されるアクションをキューに入れること。

AsyncTask

AsyncTaskUIスレッドを適切かつ簡単に使用できるようにします。このクラスを使用すると、スレッドやハンドラーを操作しなくても、バックグラウンド操作を実行してUIスレッドで結果を公開できます。

欠点:

  1. デフォルトでは、アプリAsyncTaskは作成したすべてのオブジェクトを単一のスレッドにプッシュします。したがって、これらはシリアル方式で実行され、メインスレッドと同様に、特に長い作業パケットがキューをブロックする可能性があります。このため、AsyncTaskを使用して、期間が5ミリ秒より短い作業項目を処理します。

  2. AsyncTaskオブジェクトは、暗黙的な参照の問題の最も一般的な違反者でもあります。AsyncTaskオブジェクトには、明示的な参照に関連するリスクもあります。

HandlerThread

長時間実行されるスレッドで作業ブロックを実行するには、より従来的なアプローチ(5ミリ秒のワークロードに使用する必要があるAsyncTaskとは異なります)と、そのワークフローを手動で管理する機能が必要になる場合があります。ハンドラースレッドは、事実上、キューから作業を取得して操作する長時間実行スレッドです。

ThreadPoolExecutor

このクラスは、スレッドのグループの作成を管理し、それらの優先順位を設定し、それらのスレッド間で作業がどのように分散されるかを管理します。ワークロードが増減すると、クラスは、ワークロードに適応するために、より多くのスレッドをスピンアップまたは破棄します。

ワークロードが多く、シングルHandlerThreadでは不十分な場合は、ThreadPoolExecutor

ただし、ソケット接続を稼働させたいのですが。これはハンドラーまたはスレッド、あるいはAsyncTaskで実行する必要がありますか?UIの操作はまったく必要ありません。使用するパフォーマンスに違いはありますか?

UIの操作は必要ないため、に行くことはできませんAsyncTask。通常のスレッドはあまり役に立たないためHandlerThread、最良のオプションです。ソケット接続を維持する必要があるため、メインスレッドのハンドラーはまったく役に立ちません。を作成し、のルーパーからHandlerThreadを取得します。HandlerHandlerThread

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

UIスレッドと通信する場合は、もう1つのハンドラーを使用して応答を処理できます。

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:スレッドで乾杯

于 2017-08-27T19:35:07.720 に答える
5

私の意見では、スレッドはソケット接続を行うための最も効率的な方法ではありませんが、スレッドの実行に関して最も多くの機能を提供します。経験上、スレッドを長時間実行すると、デバイスが非常に熱くなり、リソースを大量に消費するためです。単純なものでもwhile(true)数分で電話を加熱します。UIの相互作用は重要ではないと言えば、AsyncTask長期的なプロセス向けに設計されているため、おそらくそれは良いことです。これは私の意見です。

アップデート

上記の答えは無視してください!私は2011年に、Androidの経験が今よりもはるかに少ないときに、この質問に答えました。上記の私の答えは誤解を招き、間違っていると見なされます。多くの人が私を訂正する以下にコメントしたので、私はそれをそこに残します、そして私は私のレッスンを学びました。

このスレッドには他にもはるかに優れた答えがありますが、少なくとももっと適切な答えを教えてあげます。通常のJavaを使用しても問題はありませんThread。ただし、これを誤って実行するとプロセッサに非常に負荷がかかる可能性があるため、実装方法には十分注意する必要があります(最も顕著な症状は、デバイスの過熱である可能性があります)。AsyncTasksは、バックグラウンドで実行するほとんどのタスクに非常に理想的です(一般的な例は、ディスクI / O、ネットワーク呼び出し、およびデータベース呼び出しです)。ただし、AsyncTaskユーザーがアプリを閉じた後、またはデバイスをスタンバイ状態にした後も続行する必要がある、特に長いプロセスには使用しないでください。ほとんどの場合、UIスレッドに属さないものはすべて、で処理できますAsyncTask

于 2011-08-06T00:43:09.070 に答える
5

AsyncTaskバックグラウンドで実行される数秒以下の操作を実行するように設計されています(サーバーからのメガバイトのファイルダウンロードや、ファイルIO操作などのCPU集約型タスクの計算にはお勧めしません)。長時間実行する操作を実行する必要がある場合は、Javaネイティブスレッドを使用することを強くお勧めします。Javaには、必要なことを実行するためのさまざまなスレッド関連のクラスが用意されています。HandlerUIスレッドを更新するために使用します。

于 2014-03-24T09:46:24.737 に答える
2
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();
    }

}
于 2017-07-10T06:30:42.100 に答える
2

どちらを選択するかは、要件に基づいています。

ハンドラーは主に他のスレッドからメインスレッドに切り替えるために使用されます。ハンドラーはルーパーに接続され、実行可能なタスクをキューに入れます。したがって、すでに他のスレッドにいてメインスレッドに切り替える場合は、非同期タスクや他のスレッドの代わりにハンドルが必要です

ルーパーではないメインスレッド以外で作成されたハンドラーがハンドルを作成したときにエラーが発生しない場合は、そのスレッドをロッパーにする必要があります

AsyncTaskは、バックグラウンドスレッドで実行され、その結果をメインスレッドに提供するコードを数秒間実行するために使用されます*** AsyncTaskの制限事項 1.非同期タスクはアクティビティのライフサイクルに関連付けられておらず、ローダーが破棄するのに対し、アクティビティが破棄されても実行を継続しますこの制限はありません。2。すべての非同期タスクは、実行のために同じバックグラウンドスレッドを共有します。これは、アプリのパフォーマンスにも影響します。

スレッドはアプリでバックグラウンド作業にも使用されますが、メインスレッドでのコールバックはありません。要件が1つのスレッドではなく一部のスレッドに適しており、タスクを何度も実行する必要がある場合は、スレッドプールエグゼキューターの方が適しています。たとえば、グライドのような複数のURLからの画像の読み込みの要件。

于 2019-08-07T09:57:30.017 に答える
1

ここで例を挙げて質問に答えてみましょう:)-MyImageSearch[メインアクティビティ画面の画像をここで参照してください-テキストの編集/検索ボタン/グリッドビューが含まれています]

MyImageSearch

MyImageSearchの説明-ユーザーが編集テキストフィールドに詳細を入力して検索ボタンをクリックすると、flickrが提供するWebサービスを介してインターネット上の画像を検索します(キー/シークレットトークンを取得するには、そこに登録するだけです) -検索の場合、HTTPリクエストを送信し、個々の画像のURLを含む応答としてJSONデータをGETします。これを使用して、グリッドビューを読み込みます。

私の実装-メインアクティビティでは、AsyncTaskを拡張してdoInBackGroundメソッドでHTTPリクエストを送信し、JSON応答をフェッチして、FlickrAdapterを介してGridViewを更新するために使用するFlickrItemsのローカルArrayListを更新する内部クラスを定義します(BaseAdapterを拡張します)そして、AsyncTaskのonPostExecute()でadapter.notifyDataSetChanged()を呼び出して、グリッドビューをリロードします。ここで、HTTPリクエストはブロッキング呼び出しであることに注意してください。これは、AsyncTaskを介して行ったためです。また、アイテムをアダプターにキャッシュして、パフォーマンスを向上させたり、SDカードに保存したりできます。FlickrAdapterで拡張するグリッドには、実装にプログレスバーと画像ビューが含まれています。以下に、私が使用したmainActivityのコードを示します。

今すぐ質問に答える-個々の画像をフェッチするためのJSONデータを取得したら、ハンドラー、スレッド、またはAsyncTaskを介して画像をバックグラウンドで取得するロジックを実装できます。ここで、ダウンロードした画像はUI /メインスレッドに表示する必要があるため、コンテキストにアクセスできないため、スレッドをそのまま使用することはできないことに注意してください。FlickrAdapterでは、私が考えることができる選択肢は次のとおりです。

  • 選択肢1:LooperThreadを作成します[スレッドを拡張します]-そして、このスレッドを開いたままにして、1つのスレッドでイメージを順番にダウンロードし続けます[looper.loop()]
  • 選択肢2:スレッドプールを利用し、ImageViewへの参照を含むmyHandlerを介してランナブルを投稿しますが、グリッドビューのビューがリサイクルされるため、インデックス4の画像がインデックス9に表示されるという問題が発生する可能性があります[ダウンロードもっと時間がかかる]
  • 選択肢3[これを使用しました]:スレッドプールを利用して、ImageViewのインデックスとImageView自体に関連するデータを含むmyHandlerにメッセージを送信します。したがって、handleMessage()を実行している間、currentIndexがのインデックスと一致する場合にのみImageViewを更新します。ダウンロードしようとした画像。
  • 選択肢4:AsyncTaskを使用してバックグラウンドで画像をダウンロードしますが、ここではスレッドプールに必要なスレッドの数にアクセスできず、Androidのバージョンによって異なりますが、選択肢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);
    }
}

私の答えが長い間、より細かい詳細のいくつかを理解するのに役立つことを願っています。

于 2014-08-24T18:43:52.250 に答える
0

スレッド

アプリを起動すると、コードを実行するプロセスが作成されます。コンピューティングリソースを効率的に使用するために、プロセス内でスレッドを開始して、一度に複数のタスクを実行できるようにすることができます。したがって、スレッドを使用すると、アイドル時間を使わずにCPUを効率的に利用して、効率的なアプリを構築できます。

Androidでは、すべてのコンポーネントがメインスレッドと呼ばれる単一のスレッドで実行されます。Androidシステムはタスクをキューに入れ、メインスレッドで1つずつ実行します。長時間実行されるタスクが実行されると、アプリが応答しなくなります。

これを防ぐために、ワーカースレッドを作成し、バックグラウンドまたは長時間実行されるタスクを実行できます。

ハンドラ

androidはシングルスレッドモデルを使用するため、UIコンポーネントはスレッドセーフではなく作成されます。つまり、作成したスレッドのみがアクセスする必要があります。つまり、UIコンポーネントはメインスレッドでのみ更新する必要があります。UIコンポーネントはメインスレッドで実行されるため、ワーカースレッドで実行されるタスクはUIコンポーネントを変更できません。ここでハンドラーが登場します。Looperを使用するハンドラーは、新しいスレッドまたは既存のスレッドに接続し、接続されたスレッドに含まれるコードを実行できます。

ハンドラーにより、スレッド間の通信が可能になります。ハンドラーを使用すると、バックグラウンドスレッドは結果を送信でき、メインスレッドに接続されているハンドラーはメインスレッドのUIコンポーネントを更新できます。

AsyncTask

androidが提供するAsyncTaskは、スレッドとハンドラーの両方を使用して、バックグラウンドで単純なタスクを実行し、バックグラウンドスレッドからメインスレッドに結果を簡単に更新できるようにします。

例については、Androidスレッド、ハンドラー、非同期タスク、およびスレッドプールを参照してください。

于 2018-03-28T07:19:39.283 に答える
-2

Handler-スレッド間の通信媒体です。Androidでは、ハンドラーを介してメッセージを作成および送信することにより、メインスレッドと通信するために主に使用されます

AsyncTask-バックグラウンドスレッドで長時間実行されるアプリケーションを実行するために使用されます。nAsyncTaskを使用すると、バックグラウンドスレッドで操作を実行し、アプリケーションのメインスレッドで結果を取得できます。

Thread-並行性と最大CPU使用率を達成するための軽量プロセスです。Androidでは、スレッドを使用して、アプリのUIに触れないアクティビティを実行できます。

于 2017-02-09T13:39:16.337 に答える