Locked History Actions

Diff for "Android/Handler"

Differences between revisions 5 and 6
Deletions are marked like this. Additions are marked like this.
Line 26: Line 26:
このアプローチはSwingだけでなくSWTも同様であり、Androidの仕様はヘンすぎる。

Handler

Handlerのマニュアルには以下の記述がある。

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

が、Javaを知ってる人間がこれを読めば頭の中が「?」で埋め尽くされることは必至である。Javaのスレッドにこんな機能は存在しない。 つくづく不親切な記述である。結局のところ、Androidのソースコードを読まなければこの疑問は解決しない。

ソースを読んでみればすぐに理解できるのだが、Handlerの動作にはLooperというオブジェクトが必要であり、そのLooperオブジェクトはスレッドごとにThreadLocalを使用して保持されているのである。だから、勝手に作成したThreadに対してHandlerを作成しても例外が発生してしまう。このようなスレッドに対してはあらかじめLooperオブジェクトを作成して登録しておかなければならない。

さらに、HandlerにはLooperオブジェクトを引数として与えることのできるコンストラクタが用意されているのだから「of the thread that is creating it」という部分は間違いである。

なぜHandlerは複数作成することができるのか

GUIスレッドとそれ以外のスレッドの同期を行うためなら、Swingにあるような機能(SwingUtilities.invokeLater)で十分であると思われる。 この場合、あらゆる場所からこの同じstaticなメソッドを呼び出すことができる。専用のオブジェクトを作成する必要はない。

Android環境はメモリ量が小さいのに、どういうわけでSwingよりメモリを要求されるアプローチをとっているのだろうか? 考えられることと言えば、「一つのアプリケーション中の異なるアクティビティのGUIスレッドを異なるものになる」ということしかありえないのだが、ほんとうにこのようなことが起こるのだろうか?

しかし、いくらなんでもこのような設計はヘン過ぎるだろう。Applicationオブジェクトの作成やコールバックの呼び出し、アクティビティAの作成やコールバックの呼び出し、アクティビティBの。。。がすべて同じスレッドで無いと不便で仕方がない。未確認だが、これらは同一のスレッドで無ければ設計としてはマトモとは言えない。

したがって、Handlerの仕様は一般的なアプリケーションプログラマに使わせるにしては冗長過ぎることは明らかだ。一つのアプリ側にはただ一つのHandlerがあれば十分なのである。Swingのアプローチの方が正しい。

このアプローチはSwingだけでなくSWTも同様であり、Androidの仕様はヘンすぎる。