非同期処理を組んでると、
「別スレッド上でも Handler みたいなキュー管理がしたい」
って時があったりしますよねー。(きっと)
そんなとき、HandlerThread を使うとわりと簡単に実装できたりする。
HandlerThread は java.lang.Thread を継承したクラスで、
android標準の Handler と組み合わせて使うための仕組みが入ってたり。
具体的な使い方。
まずは Handler(defaultコンストラクタ) を使う場合。
実行すると当然 「main」 と出力される。
当然、mainスレ上でキューが実行される。
これは問題ないですね。
次に Handler+HandlerThread の場合。
実行すると 「other」 と出力される。
キューが実行されてるスレッドが mainスレ から 別スレ に変更されます。
もちろんこの Handlerインスタンス は別スレ上で使用してOK。
手順をまとめるとこんなかんじ。
- 別スレッド(HandlerThread)を生成
- 別スレ開始
- HandlerThreadインスタンス から Looperインスタンス 取得
- Handlerインスタンスを生成(3で取得した Looperインスタンス を 引数指定)
- 4 で作成した Handlerインスタンス を使用(Handler#post 等)
今まで PriorityBlockingQueue とか使って、
自前のキュー管理クラス作ってた自分涙目。
キューをFIFOで実行するだけのキュー管理であれば、
このやり方でまったく問題なさそうですね。
framework ではどうやってるのかなーと思い、
Looper、Handler、HandlerThread のソースを読んでみた。
ポイントはこのあたり。
- コンストラクタ Handler(default) は「mainスレッド上で作成された」 Looperインスタンス を使用
- コンストラクタ Handler(Looper) は「引数で渡された」 Looperインスタンス を使用
- Looperインスタンスは Looper#prepare を呼び出すと生成される(ThreadLocal保持)
- HandlerThread は Thread を継承したクラス
- HandlerThread#run の中で Looper#prepare を呼び出している
Looperインスタンスの生成場所 の違い。
0 件のコメント:
コメントを投稿