シングルキャスト

AndroidのViewを外部から拡張しようとする時に、一番の障壁となるのはイベント通知メカニズムが今時シングルキャストである点だろう。

イベントドリブンプログラミングにおいて、イベント通知を待ち続けるリスナを

    • 一つしか登録できない : シングルキャスト-イベント
    • 複数登録できる : マルチキャスト-イベント

と呼ぶ。(言語やプラットホームによっては〜デリゲート、〜コールバックと呼んだりもする)

JavaC#等、今時のGUIを扱うプログラミングプラットホームは普通にマルチキャスト-イベントを扱えるが、Androidの場合、なぜかシングルキャストのイベントハンドラしか用意されていない。

  • 例) View#setOnClickListenerメソッド
public void setOnClickListener(OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    mOnClickListener = l; //List等に追加しないので、以前に登録されていたリスナには通知されない
}

Viewのイベントハンドラがシングルキャスト = 複数のイベントハンドラを登録できないということは、その外部からViewの任意のイベントへ割り込むことができない、イベントを処理する前/後に処理を挿入できないことを意味する。これでは、Viewクラスのサブクラスを作らない限り、その振る舞いを拡張できないということになる。

次手としては、現在登録されているイベントリスナを取得して、自らのマルチキャスト用のリスナに追加した上で再び登録する方法が考えられるが、この手が使えるのは現在のイベントリスナが何らかの形で外部に公開されているのが条件だ。例えば上記のView#OnClickListenerの場合、内部フィールドになっているmOnClickListenerを取得するためのアクセサが実装されていないため、この手も使えない。

結局、Viewの実装にちょいと割り込みを入れたい場合であっても、現状はViewクラスをextendsするしかない。ちょっと残念だ。