何かを実行する必要があるとき非同期的に、例えばlong running taskまたはネットワーク、または何らかの理由で、新しいスレッドを開始して、正常に動作します。 Handlerの作成と実行も同様に機能します。違いは何ですか?それぞれをいつ使用する必要がありますか? Handler
ではなくThread
を使用する利点/理由は何ですか?
PS。 -この質問のために、AsyncTask
を無視しましょう。 -Handler().postDelayed
ユースケースは明確です。この質問のために、タスクをすぐに開始する必要があると仮定しましょう。
あなたがやっていることが「重い」なら、それをスレッドでやるべきです。独自のスレッドで明示的に起動しない場合、メイン(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、重い演算など)を行うときはいつでもスレッドを使用する必要があります。
ハンドラとスレッドは実際には2つの異なるものです。
長時間実行されるジョブを実行するには、スレッドを作成する必要があります。
ハンドラーは、2つのスレッド間で通信するのに非常に便利なオブジェクトです(たとえば、バックグラウンドスレッドはUIを更新する必要があります。ハンドラーを使用して、バックグラウンドスレッドからUIスレッドにRunnableをポストできます)。
そのため、ハンドラとスレッドのどちらも選択できません。スレッドを使用して重い仕事をしてください! (バックグラウンドスレッドが別のスレッドで実行されるジョブをトリガーする場合、ほとんどの場合UIスレッドでハンドラーを使用できます)
Handler
とThread
は2つの異なるものですが、互いに矛盾していません。 Handler
とThread
を同時に使用できますが、実際には各Handler
をThread
で実行する必要があります。
詳細については、 この記事をご覧ください をお勧めします。
Handler
は同じThread
で実行され、Thread
は異なるスレッドで実行されます。
同じスレッドで何かを実行する必要がある場合はハンドラを使用します、通常はGUI要素またはそのようなものです。
他のことを行うためにメインスレッドを自由に保ちたい場合は、スレッドを使用します。かなりの時間がかかるものにこれを使用します。
ハンドラーは、バックグラウンドとUIスレッド間の最適な通信方法です。通常、ハンドラーはスレッドのメッセージキューに関連付けられ、メッセージを送信するために使用され、メッセージに実行可能です。
USE:
スレッド:UIスレッドよりsaperate(Background)スレッドでタスクを実行します。 (UIスレッドのブロックを解除するのに役立ちます)
HandlerUIとバックグラウンドスレッド間の通信に使用されます。
これをご覧ください 記事
新しいスレッドからユーザーインターフェイスを更新する必要がある場合は、ユーザーインターフェイススレッドと同期する必要があります。
これには、Android.os.HandlerクラスまたはAsyncTasksクラスを使用できます。
Handlerクラスは、ユーザーインターフェイスを更新できます。ハンドラーは、MessageまたはRunnableクラスのインスタンスを受け取るためのメソッドを提供します。
スレッドは、sendMessage(Message msg)メソッドまたはsendEmptyMessage()メソッドを介してメッセージを投稿できます。
...詳細 ここ スレッドなどについて(異なるスレッド化メカニズムと同期メカニズム、および何をいつ使用するかを含む)
スレッドではなくハンドラーを使用する利点/理由は何ですか?
Handler を使用すると、スレッドのRunnable
に関連付けられたMessageおよびMessageQueue
オブジェクトを送信および処理できます。各Handler
インスタンスは、単一のスレッドとそのスレッドのメッセージキューに関連付けられています。
新しいHandler
を作成すると、それはそれを作成しているスレッドのスレッド/メッセージキューにバインドされます。その時点から、メッセージと実行可能ファイルをそのメッセージキューに配信し、それらを実行します。メッセージキューから。
ハンドラーには主に2つの用途があります。
Javaスレッドを使用する場合、メインスレッドとの同期、スレッドのキャンセルなど、自分で何かを処理する必要があります。
この単一のスレッドは、ThreadPoolExecutor
またはExecutorService
APIを使用しない限り、スレッドプールを作成しません。
(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
タスクは単一のスレッドで実行されます。
Handler
は、Thread
と組み合わせて使用して、キューメカニズムを作成できます。 Uouはhandler
を使用してThread
Looper
に何かを投稿できます