Twitter4J のサンプルを書いていて、非同期 API 使った方が良さそうだなぁという場面に出くわしたので、ちょっと 非同期 API を試してみることに。
非同期 API 概要
非同期 API を使用する大まかな手順は
といった感じです。 概ね
- TwitterFactory → AsyncTwitterFactory
- Twitter → AsyncTwitter
となっているだけですが、TwitterListener インターフェースのインスタンスの作成・設定が同期 API との違いです。
TwitterListener インターフェース
TwitterLisener インターフェースは、(AsyncTwitter を介して) twitter に何らかの処理を行った後、そのレスポンスに対して処理を続行したい場合に使用します。 そう言えば JavaDoc 見ると、AsyncTwitter インターフェースには Twitter インターフェースと同名、同引数のメソッドが定義されてますが、返り値は全て void になってますね。 AsyncTwitter のどのメソッドを呼ぶと、レスポンスが TwitterListener のどのメソッドに返されるのかはメソッド名を見比べて判断するしかないかと思います(大抵簡単に分かります)。
で、TwitterListener インターフェースにはたくさんのメソッドが定義されていますが、1つの TwitterListener を作るのにそれら全てを実装するのは面倒過ぎるので、通常は TwitterAdapter クラスを使用して TwitterListener オブジェクトを作成します。 メソッドを1つ2つしか実装しないなら、無名クラスで充分でしょう。 使い方は以下のサンプル・コードを参照のこと。
サンプル・コード
では、非同期 API のサンプルを見ていきましょう。 OAuth 認証に必要な twitter4j.properties は既に用意されているとします(設定はこちら参照)。
ステータスの更新
同期 API でステータスを更新する方法はこちら。 非同期 API では以下のようにします:
@Grab('org.twitter4j:twitter4j-async:2.2.5') import twitter4j.* def twitter = new AsyncTwitterFactory().getInstance() // TwitterListener オブジェクトの作成 def listener = new TwitterAdapter() { @Override void updatedStatus(Status status){ println "Successfully updated the status to [$status.text]." } @Override void onException(TwitterException ex, TwitterMethod method) { println method.name() ex.printStackTrace() } } twitter.addListener(listener) // AsyncTwitter に TwitterListener を設定 twitter.updateStatus('async twitter test.') Thread.sleep(10000) // 処理完了待ちなぅ
- 非同期 API を使うのに必要なライブラリは twitter4j-async です。 同期 API が定義されている twitter-core も使用されますが、twitter-async から辿ってダウンロードされるので特に書く必要はありません。
- 最後の「Thread.sleep()」がないと、処理の完了を待たずにメインスレッドが終了し、それに伴って非同期で実行されるハズの処理も終了されてしまうようです。 ここでは10秒(=10000ミリ秒)だけスリープしてますが、それが多いか少ないかは環境によるかと。 非同期実行しているスレッドに対する join() メソッドみたいなのがあれば便利かも*2。
まぁ、コードのほとんどが TwitterListener (というより TwitterAdapter)の作成部分に費やされてます。
ユーザーリストを作成してメンバーを加える
次は「ユーザーリストを作成してメンバーを加える」サンプル。 同期 API の場合はこちら参照。 「ユーザーリストの作成」と「ユーザーリストへのユーザーの追加」が別々のリクエストになるためか、同期 API だとうまくいかない(ユーザーリストが2つ作成されるなど)場合があります。 非同期 API ならそういったことは起こらないんでしょう:
@Grab('org.twitter4j:twitter4j-async:2.2.5') import twitter4j.* def twitter = new AsyncTwitterFactory().getInstance() def members = [ 'scandal_haruna', 'scandal_tomomi', 'scandal_mami', 'scandal_rina' ] as String[] // TwitterListener オブジェクトの作成 def listener= new TwitterAdapter() { @Override void createdUserList(UserList userList) { println "Created user list : $userList.name" println "Member count : $userList.memberCount" // AsyncTwitter オブジェクトを再度使って処理をリクエスト twitter.addUserListMembers(userList.id, members) } @Override void addedUserListMembers(UserList userList){ println "Added users to user list : $userList.name" println "Member count : $userList.memberCount" } @Override void onException(TwitterException ex, TwitterMethod method) { println method.name() ex.printStackTrace() } } twitter.addListener(listener) // AsyncTwitter に TwitterListener を設定 twitter.createUserList('scandal', true, 'THE Girls Band.') Thread.sleep(20000) // 処理完了待ちなぅ
- AsyncTwitterFactory オブジェクトは使い回しが利くように実装されているそうですが、AsyncTwitter オブジェクトもこのサンプルでやっている程度には使い回しが利くようです。
Twitter API ポケットリファレンス (POCKET REFERENCE)
- 作者: 山本 裕介
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/15
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 247回
- この商品を含むブログ (41件) を見る