2019/09/12

Androidアプリ開発:イベントドリブンなプログラミング

Androidのアプリでは、いろいろな処理は、UI操作からのイベント処理、Activityのライフサイクルに関するコールバックなどのイベントから始まる。これらのイベントは、いわゆるUIスレッドに配信される。UIスレッドは各種イベントの受付と、UIの更新を受け持つ。Android全体の動作をスムーズにするためには、イベント処理すみやかに終了して、Android OSに制御を返さなければならない。UIスレッドでは、何かの処理の完了を待つことも許されない。

つまり、時間のかかる処理は別スレッドで実行しなければならない。ネットワークからデータを取得する処理も、Activityのイベント処理とは別のスレッドにしなければならない。
これは何を言っているかというと、「更新ボタンがタップされたから、データを新たに取得して画面を更新する」、「送信ボタンが押されたので、データを送信し、結果を取得して、画面を更新する」といった処理を、一連のフローで記述できない、ということだ。これらを、何某かのイベント契機で実行される処理に分解しなければならない。いわゆる、イベントドリブンな形に分解しなければならない。これは、とても大きなポイント。

「更新ボタンがタップされたから、データを新たに取得して画面を更新する」は、
・更新ボタンタップ → データ取得処理を開始する。
・データ取得完了 → 画面を更新する。
という2つのイベント処理に分解して実装しなければならない。それぞれ、コンポーネントのイベントリスナー、非同期処理の完了ハンドラに実装する形になる。

私が小さなAndroidアプリを書いた印象では、処理が複数のイベント処理に分割されるため、慣れるまでは見通しが悪く感じた。一方で、それぞれの処理がコンパクトになり、その処理自体は簡潔で単純になるので、かえってスッキリするようにも感じられる。多分、テストもしやすくなるんだろうなと思う。

注意するところは、イベント処理の実装の仕方がいろいろあり、迷子になりやすいことか。クラスのメソッドとして実装される場合は処理を探しやすいが、匿名クラスのオブジェクトのメソッドによる実装を多用すると、個人的には見通しが悪くなると感じる。

例えば、UIコンポーネントのイベント処理は、イベントリスナーをActivityのメソッドとして実装することもできるし、イベントリスナーのインタフェイスを実装するオブジェクトをUIコンポーネントにリスナーとして登録することでも実現できる。

一概に、どちらが良いとは言えない。個人的には、クラスのメソッドとしてイベント処理が実装されていたほうが、コードを探しやすくてよいように思う。匿名クラスの実装にもメリットはあり、匿名クラスであるべき場合もある。まぁ、多分、古い人間なんでしょう。

いずれにしても、イベント処理を普通のクラスのメソッドで実装するのか、匿名クラスのメソッドで実装するのか、一貫したスタイルを決めておくのが良いと思われる。

で、なるほどなー、そうかそうか、完全にイベントドリブンで考えないといけないんだ、といってその後何も考えずにイベント処理を作り込んでいくと、、、巨大で複雑なActivityができあがる。「あれ? なんかActivityのコードが膨らんでいるけど、こんなんでいいんだっけ?」と薄々心配しているのを放置して先に進み、機能追加してイベント処理が増えてくると、「これはなにか間違っている」、と感じるくらい、あっという間にコードが膨らむ。

次の罠、"Fat Activity”だ。

0 件のコメント :

コメントを投稿