web-dev-qa-db-ja.com

Android:Handler()をいつ使用し、Threadをいつ使用する必要がありますか?

何かを実行する必要があるとき非同期的に、例えばlong running taskまたはネットワーク、または何らかの理由で、新しいスレッドを開始して、正常に動作します。 Handlerの作成と実行も同様に機能します。違いは何ですか?それぞれをいつ使用する必要がありますか? HandlerではなくThreadを使用する利点/理由は何ですか?

PS。 -この質問のために、AsyncTaskを無視しましょう。 -Handler().postDelayedユースケースは明確です。この質問のために、タスクをすぐに開始する必要があると仮定しましょう。

126
JRun

あなたがやっていることが「重い」なら、それをスレッドでやるべきです。独自のスレッドで明示的に起動しない場合、メイン(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、重い演算など)を行うときはいつでもスレッドを使用する必要があります。

163
FoamyGuy

ハンドラとスレッドは実際には2つの異なるものです。

長時間実行されるジョブを実行するには、スレッドを作成する必要があります。

ハンドラーは、2つのスレッド間で通信するのに非常に便利なオブジェクトです(たとえば、バックグラウンドスレッドはUIを更新する必要があります。ハンドラーを使用して、バックグラウンドスレッドからUIスレッドにRunnableをポストできます)。

そのため、ハンドラとスレッドのどちらも選択できません。スレッドを使用して重い仕事をしてください! (バックグラウンドスレッドが別のスレッドで実行されるジョブをトリガーする場合、ほとんどの場合UIスレッドでハンドラーを使用できます)

61
ben75

HandlerThreadは2つの異なるものですが、互いに矛盾していません。 HandlerThreadを同時に使用できますが、実際には各HandlerThreadで実行する必要があります。

詳細については、 この記事をご覧ください をお勧めします。

enter image description here

28
pierrotlefou

Handlerは同じThreadで実行され、Threadは異なるスレッドで実行されます。

同じスレッドで何かを実行する必要がある場合はハンドラを使用します、通常はGUI要素またはそのようなものです。

他のことを行うためにメインスレッドを自由に保ちたい場合は、スレッドを使用します。かなりの時間がかかるものにこれを使用します。

18
PearsonArtPhoto

ハンドラーは、バックグラウンドとUIスレッド間の最適な通信方法です。通常、ハンドラーはスレッドのメッセージキューに関連付けられ、メッセージを送信するために使用され、メッセージに実行可能です。

USE:

スレッド:UIスレッドよりsaperate(Background)スレッドでタスクを実行します。 (UIスレッドのブロックを解除するのに役立ちます)

HandlerUIとバックグラウンドスレッド間の通信に使用されます。

これをご覧ください 記事

13

新しいスレッドからユーザーインターフェイスを更新する必要がある場合は、ユーザーインターフェイススレッドと同期する必要があります。

これには、Android.os.HandlerクラスまたはAsyncTasksクラスを使用できます。

Handlerクラスは、ユーザーインターフェイスを更新できます。ハンドラーは、MessageまたはRunnableクラスのインスタンスを受け取るためのメソッドを提供します。

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

...詳細 ここ スレッドなどについて(異なるスレッド化メカニズムと同期メカニズム、および何をいつ使用するかを含む)

4
Beachwalker

スレッドではなくハンドラーを使用する利点/理由は何ですか?

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

新しいHandlerを作成すると、それはそれを作成しているスレッドのスレッド/メッセージキューにバインドされます。その時点から、メッセージと実行可能ファイルをそのメッセージキューに配信し、それらを実行します。メッセージキューから。

ハンドラーには主に2つの用途があります。

  1. メッセージとRunnablesを将来のある時点として実行されるようにスケジュールするには
  2. 自分のスレッドとは異なるスレッドで実行されるアクションをenqueueします。

Javaスレッドを使用する場合、メインスレッドとの同期、スレッドのキャンセルなど、自分で何かを処理する必要があります。

この単一のスレッドは、ThreadPoolExecutorまたはExecutorService AP​​Iを使用しない限り、スレッドプールを作成しません。

(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タスクは単一のスレッドで実行されます。

Android:スレッドでトースト

2
Ravindra babu

Handlerは、Threadと組み合わせて使用​​して、キューメカニズムを作成できます。 Uouはhandlerを使用してThreadLooperに何かを投稿できます

1
Blackbelt