moxt

Just another Blog site

AndroidのHandlerって何?

      2015/07/03

Handlerは何?と、Handlerを直視するとHandlerの存在意義というかなんというか文脈を捉えることが難しい。
なので、まずはAndroidがシングルスレッドである、という所からスタートしてHandlerに向かってゆく。

Androidはシングルスレッド

AndroidはJavascriptやActionscriptのように1つのループがグルグル回ってイベントを逐次捌くシングルスレッド方式。
なので、各イベント内で重い処理やブロッキングが発生するような処理(同期的なHTTP通信とか?)走らせると処理落ちが発生してアプリの動作がカクつく。

Androidでマルチスレッドしたい

なので、先にあげたHTTP通信とか大量の計算が必要な処理をしたいときはメインのスレッドとは別のスレッドを生成、そのスレッド内で処理を行うようにする。

こんな感じ

Threadを継承して独自の処理を記述する
Runnableを実装したインスタンスをThreadインスタンス生成時に与える

スレッド内で処理が完結するならこれで終わり。

スレッド間で通信したい

完結しない場合もある。
例えば、HTTP通信してきた結果をTextViewに表示したい。とか。
スレッドにViewの参照渡して更新したらいいんじゃないの?って思うんだけど、それができないようになってる。
UI系の更新処理はメインスレッド上で呼び出さないとダメなんだって。
こういう別スレッド云々関係なく、普段のUI系の更新処理もメインスレッド上で行ってる。
処理をあちこちのスレッドから実行せず集約することでカオスにならないようにしてるのかな。

というわけで、メインスレッドに対して何かしらの方法で処理の内容を伝えないといけない。
どうやるのか?

ある別スレッド→メインスレッド

想像するに2つのステップがある気がする

  • 別スレッドはメインスレッドに対して何かしらの方法で処理の内容を投げる
  • メインスレッドは別スレッドからとんできた処理内容のメッセージを受け取って、そこに書いてる処理を実行する

真打ちHandler

ここでHandlerとLooperが登場するわけ。

http://tachesimazzoca.github.io/wiki/android/threads.html

Android では、スレッド毎に MessageQueue を持ち、Looper が順番に送信されたメッセージをキューから取り出し、処理を行なっている。

Handler により、このキューにメッセージを送信することができる。

どのメッセージキューに対してメッセージを送信するか、と指定するわけではない。ちょっと混乱する。
MessageQueueからメッセージを取り出すLooperを指定してメッセージを送るようなかんじ。

http://d.hatena.ne.jp/sankumee/20120329/1333021847

↑この記事が分かりやすかった。
Handlerインスタンスを生成するときに送り先Looperを指定してる。
で、post(Message) or post(Runnable)って感じ。

Looper.getMainLooper()っていうメソッドがあって、これを呼べばメインスレッドに紐づくLooperが取得できる。
なので、Looper.getMainLooperの返り値をHandlerに注入してインスタンス作ってやればOK

ちなみ、メインスレッドのLooperはAndroidアプリ起動時に勝手につくられるみたい。
なので、明示的にprepareする必要はない。
詳細はgrepcodeで確認できる。

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/os/Looper.java#Looper.myLooper%28%29

おわり

Handler系の記事はもっと洗練されたヤツあるので、いまさら感ある。
でも、こういう感じで書きながら流れに沿って理解をするってのは血肉度高まるし良いよね。

 - プログラミング

336px




336px




  • このエントリーをはてなブックマークに追加
  • follow us in feedly

  関連記事