-
Notifications
You must be signed in to change notification settings - Fork 353
2.12. Handler と Looper
GitHub Pagesへ移行しましたmixi-inc.github.ioへお願いします。
wikiの方はしばらくしたら消していきます
この章では、Handler と Looper について解説します。
参考:Communicating with the UI thread | Android Developers
参考:Handler | Android Developers
参考:Looper | Android Developers
Looperは、Looperが初期化されたスレッド内で作られたメッセージを順に処理するオブジェクトです。
Activity などのコンポーネントでは、標準でこのLooperが UI スレッド上で初期化されます。これによって、Activity や Fragment で受け取った UI のイベントをメッセージとしてLooperに投げると、メインスレッド上でそのメッセージが実行されるようになります。
メインスレッド用のLooperを取得する場合は以下のようにします。
Looper looper = Looper.getMainLooper();
Looperは、その初期化を実行したスレッド内でメッセージを順に処理するように振舞うので、UI スレッドでない別のスレッドにも適用できます。
こうすることで、別スレッドにおいても、何らかのイベントをメッセージとして受け付けることが出来るようになります。
public class MyThread extends Thread {
@Override
public void run() {
Looper.prepare(); // 初期化
// ...
Looper.loop(); // メッセージキューを開始
}
}Looperの仕組みによって、メッセージを受け付けて順に処理できるようになりますが、一方で、Looperに対してメッセージを送る役割を持つものが必要になります。
この、Looperに対してメッセージを送る役割を担っているのがHandlerです。
多くは、別スレッドから UI スレッドへメッセージを送ることで、別スレッド内で UI の更新を促す為の仕組みとして用いられます。
下記のようにHandlerインスタンスを生成すると、生成したインスタンスのLooperにメッセージを送るHandlerが作られます。
Handler handler = new Handler();
もし、メインスレッドの Looper にメッセージを送るHandlerインスタンスを生成する場合は、以下のようにします。
Handler handler = new Handler(Looper.getMainLooper());
メッセージを作成し、その内容をLooperのキューに積んで実行させるには、以下のようにします。
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
// メインスレッド上で実行させたい内容
}
});Handlerを内部に持ち、Looperが動作していて、適宜そのLooperにメッセージを積み上げて処理することの出来る特別なThreadです。
HandlerThreadのインスタンスが生成された時、Looper#prepare()が呼び出され、Looperの動作が始まります。この後、このスレッド用にHandlerが生成され、他のスレッドとのメッセージのやり取りが出来るようになります。
IntentServiceは内部的にHandlerThreadを使用しており、Context#startService(Intent)で渡されたIntentを順にHandlerを経由してHandlerThreadに渡しています。これによって、簡易的なジョブキューの仕組みが実現されています。
Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.