Android で Twitter4J から Streaming API 使う場合

  • 投稿日:
  • by
  • カテゴリ:

デフォルトのまま使うのは無駄な処理が多く制御もしづらいので、よっぽど単純なテスト目的を除いてやめましょう。

Twitter4J は Streaming API で受け取ったデータをマルチスレッドで処理するために内部で独自のスレッド管理をおこなってますが、これは当然というかほぼ T4J 専用に作られていて非常に応用が利きません。たとえば作られたスレッドが余っていても T4J 専用なので自分のアプリから使うことが出来なかったりします。Android でこの無駄はバッテリーにとても厳しい。

また Java 1.4 との互換性にも縛られているせいで「車輪の再発明」を強いられている感もあり、Java 1.5 環境の Android ならもっとかんたんで便利なものが手軽に利用できるのでそっちにしたほうがいい、というのもあります。

具体的には twitter4j.internal.async.Dispatcher インターフェースを実装したクラスを作って、そのクラス名を twitter4j.Configuration クラスのインスタンスに持たせるだけです。

と聞くとなんだかめんどくさそうですけど、Dispatcher の実装ってこんなのでいいんです。

これはチャーハン諸島で使ってるものですが、T4J デフォルトの DispatcherImpl.java と比べたらかんたんすぎて逆に不安になるレベル。
実際のチャーハン諸島では ThreadFatctory もオリジナルのものを使ってるので若干違うんですけど本質的には変わらないです。

ExecutorServiceExecutors 使ってるおかげで「指定した個数のスレッド固定」とか「必要に応じて生成したスレッドをプールして再利用」とかアプリの実装に合わせて挙動も変えられるのでなんとなく嬉しいかもしれません。

これのクラス名を ConfigurationBuilder#setDispatcherImpl(String) 使ったりした Configutaion インスタンスを TwitterStreamFactory に渡せば勝手に使ってくれます。

これだとシンプルすぎてオリジナルの DispatcherImpl との優劣があんまりないんですが、ExecutorService の変数をクラスの static メンバーにして各インスタンスで共有するようにすれば余ったワーカースレッドにほかの処理をさせることもできて効率的です。
AsyncTask と共有できればより効率的なんですが、こっちも自分専用の ExecutorService を使うようになってるのでそうはいかないので、やるなら AsyncTask を使った Dispatcher インターフェースの実装とかになるんでしょうか。デメリットのほうが多そう。

それはともかく、Twitter4J はちょっとした利用でもオリジナルのクラス使うよりインターフェース実装したりクラス継承したりしたほうが使いやすく、かつ大して手間も変わらなかったりします。少なくとも twitter4j.ConfigurationBuilder 使うより ConfigurationBase とか継承して必要な getter だけオーバーライドしたほうが絶対ラクだしソースも分離できて読みやすくなる。と思う。