Android Handlerは同時メッセージ パッシングの実装ですか?
を使うHandlerThread
ことで、複数のワーカースレッド間で簡単に通信できるようです。しかし、私が理解しているように、同時実行でのメッセージの受け渡しは共有メモリの使用に基づいています。Handler の実装のメカニズムを理解しようとしましたが、まだ明確ではありません。
Handler
簡単に言えば、Android はどのように機能するのでしょうか。
Android Handlerは同時メッセージ パッシングの実装ですか?
を使うHandlerThread
ことで、複数のワーカースレッド間で簡単に通信できるようです。しかし、私が理解しているように、同時実行でのメッセージの受け渡しは共有メモリの使用に基づいています。Handler の実装のメカニズムを理解しようとしましたが、まだ明確ではありません。
Handler
簡単に言えば、Android はどのように機能するのでしょうか。
はい、Handler
スレッド間メッセージ パッシングの形式を提供します。オブジェクト自体は、Handler
複数のスレッドからアクセスできる「共有メモリ」ですが、スレッドセーフであり、詳細を管理します。
より具体的には、は特定のスレッドのメッセージ キュー( )Handler
と対話するための便利なツールです。またはを に投稿すると、のスレッドのに追加されます。スレッドは、スレッドのキュー内のメッセージを継続的に処理するイベント ループ( ) を実行します。MessageQueue
Runnable
Message
Handler
MessageQueue
Handler
Looper
Android 実装の詳細を理解したい場合は、GrepCodeHandler.java
で(Android 4.1.1 の) コードを表示できます。そのクラスのドキュメントは非常に詳細で、コードは親しみやすいものです。
短い答え: はい
長い回答: @acj の回答は、Handler
/ Looper
/の詳細を短く簡潔に説明したものですMessageQueue
。ただし、いくつかの点が欠けています。
各スレッドにはメッセージ キューを関連付けることができます。スレッドに送信されたメッセージは、スレッドが実行するまでそこに格納されます。メッセージは、スレッドで実行されるループで順次処理されます。他のスレッドがメッセージをキューに投稿できます。ただし、メッセージ処理は非同期であり、通常、他のスレッドはそれをブロックしていません。
Runnable
ループの OS 実装によって実行される標準化されたメッセージ (メッセージなど) がいくつかあります。ただし、アプリケーション コードは、カスタム メッセージの処理もサポートする場合があります。
Handler
他のスレッドから特定のスレッド (通常は、Handler
オブジェクトが作成されるスレッド) のメッセージ キューにメッセージをポストする便利な方法です。Handler
はインプロセスでのみ使用でき、単一のプロセスではすべてのメモリがすべてのスレッドで共通であるため、メッセージ キューを「共有メモリ」に保持する必要はありません (この用語は、複数のプロセスからアクセス可能なメモリ領域に使用されます) 。いつもの)。
これらすべてについて留意すべき特定の事項の 1 つは、 を使用してメッセージを投稿しても、そのHandler
処理が保証されるわけではないということです。メッセージに到達する前に、さまざまな理由でスレッドが終了する可能性があります。
ご存知のように、UI スレッドでのみ UI を変更できます。したがって、バックグラウンドで何かを実行し、結果を UI に表示する必要があるが、何らかの理由で AsyncTasks を使用したくない場合 (たとえば、一度に複数のタスクを実行する必要がある場合)、Handler を使用できます。非 UI スレッドからメッセージを受信し、これらのメッセージが原因で UI に変更を加える可能性があります (もちろん UI スレッドで)。
たとえば、OnCreate() メソッドでハンドラーを実装します。
TextView tvInfo = (TextView) findViewById(R.id.tvInfo);
Handler h = new Handler() {
public void handleMessage(android.os.Message msg) {
tvInfo.setText("received: " + msg.what);
};
};
そして、ハンドラーに別の場所 (たとえば onClickListener) にメッセージを送信するスレッドを実装します。
Thread t = new Thread(new Runnable() {
public void run() {
for (int i = 1; i <= 10; i++) {
// some long action
downloadFile();
h.sendEmptyMessage("downloading of file " + i + " complete");
}
}
});
t.start();