ライブラリで久々に感動した。これはマジックだ。今回は、greenrobot/EventBus · GitHub を紹介する。
よくアクティビティに独自のコールバックオブジェクトを実装させて、それを他のクラスで渡して実行させる処理がよくあると思う。以下は例。
interface Callback { void onFinished(); } class SampleActivity extends Activity implements Callback { @Override protected void onCreate(Bundle savedInstanceState) { HogeProcess process = new HogeProcess(this); process.start(); } @Override public void onFinished() { Log.v("TAG", "finished"); } } class HogeProcess { private Callback callback; public HogeProcess(Callback callback) { this.callback = callback; } public void start() { //..... callback.onFinished(); } }
概要としてはこんな感じ。割とライブラリとかでも一般的に使われている手法だ。
ただ、このインタフェースを使ったコールバックの方法は、以下のような欠点がある。
- 毎回コールバックを作るごとにインタフェースを作らないといけない
- インプリメントがどんどん増えて複雑になっちゃう
- コールバックオブジェクトをわざわざ管理しないといけない
といった要は煩雑な処理が多くなってしまう。それを解決してくれるのが、このEventBus。
EventBus の使い方
本当に簡単。さっきのをEventBus を使って同じように作ってみる。
class SampleActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { HogeProcess process = new HogeProcess(); process.start(); } @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } public void onEvent(HogeEvent event) { Log.v("TAG", "finished"); } } class HogeEvent { } class HogeProcess { public HogeProcess() { } public void start() { //..... EventBus.getDefault().post(new HogeEvent()) } }
どうでしょう!インタフェースが消えました!それに伴ってHogeProcess内のコールバックオブジェクトも必要ないです。以下に要点をまとめよう。
- onStart, onStop, 内にregister, unregister をそれぞれ呼ぶ
- イベントを呼び出したい時に、
EventBus.getDefault().post(イベントクラス)
を呼ぶ。この時のイベントクラスの中にフィールドを持たせる事ももちろん可能。 - 受け取り側で
public void onEvent(イベントクラス event)
を定義してあげる。このイベントクラス名でかぶっていた場合だけそのイベントをキャッチすることができる。
これだけのルールだ。これだけでかなりソースが簡潔になる。そして無駄な処理が発生しなくなる。今後どのプロジェクトでも使っていきたいと思えるライブラリーだ。