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

 - プログラミング

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

  関連記事

no image
Rubyのモジュール機能とRailsのHelperについて考える

Moduleとは 参考サイトを見ながら思ったことをメモ …

no image
フロントエンド開発のメモ

最近のフロントエンド開発ではビルドランナーを使うのが常識になってきてるみたいなので。 jspm的なもっと進んだやり方でも良いんだけど、pluginが少ない、文献が少ない、自身の技術力不足、ということでビルドランナーなやり方でやる。 …

no image
意識低いRuby on Rails再入門6 ~ログイン必須のControllerを作りたい~

ログイン状態を取得するためのSessionsHelperを前に書いた 新規投稿画面を表示したり、実際に投稿するときにはログイン必須であることを保証したい。 …

no image
アプリ起動時に呼び出すStoryboardを指定したい

google-fu不足でどこにも載ってなかったのでメモ。 プロジェクト内のInfo.plistで設定できます。 …

logo_og
ReactNativeでGiphyのデータを表示する

まずは下記をサクッとパクってみる。 当方、比較的AndroiderなのでAndroidで。 …

no image
意識低いRuby on Rails再入門1

整理がてらメモ。 Contents1 …

no image
意識低いRuby on Rails再入門5

http://railstutorial.jp/chapters/sign-in-sign-out?version=4.0#top この辺を読んだメモ。 …

no image
Docker導入したらどうするの?

Dockerを導入したけど、nginxが入った環境がどこでも使えるようになった!程度だったらあんま意味ないよね。 Web開発をする上でDockerをどのように使うのが効果的か考えてみる。 …

no image
NginxとPHP-FPMを使っていたらcurl_init()が無いとエラーが出た

参考リンク 解決策 …

no image
Bower再入門

Contents1 Bowerとは何なのか2 …