DeferredTask とは
TaskQueue を、URL ハンドラの実装なしに使える便利クラスです。
通常、TaskQueue は指定された URL を叩いて Task を実行します。
この挙動は厳密な設計には便利ですが、Task の種類の数だけ URL を制御しなければなりません。
新たにルーティングを設定し、新たにコントローラメソッドを実装する必要があります。
これらを廃し、より気楽に使えるようにしたのが DeferredTask クラスです。
必要な要素はたった一つ、DeferredTask interface (#run のみ) を実装したクラスのみです。
基本的な使い方
public class SomeTask implements DeferredTask {
@Override
public void run() {
Log.d("SomeTask", "Hello World!");
}
}
// 登録
final TaskOptions option = TaskOptions.Builder.withPayload(new SomeTask());
QueueFactory.getDefaultQueue().add(option);
パラメータの渡し方
プロパティ持たせて渡します。
public class SomeTask implements DeferredTask {
private static final Logger logger = Logger.getLogger(SomeTask.class.getSimpleName());
private final String someParam;
public SomeTask(String someParam) {
this.someParam = someParam;
}
@Override
public void run() {
logger.info("Performing a task with someParam: " + someParam);
}
}
TaskQueue への登録
インスタンス化し Payload として TaskQueue に登録すれば勝手に処理されます。
final TaskOptions option = TaskOptions.Builder
.withPayload(new SomeTask("someparamvalue"));
QueueFactory.getDefaultQueue().add(option);
内部的には POST /_ah/queue/__deferred__
でこのタスクをハンドリングしてくれる。
タスクに渡したパラメータはログや TaskQueue の管理画面に出ないので注意。
Task 内でパラメータを Log しておくことをおすすめします。
注意点
DeferredTask は Serializable であることに気を付けてください。内部的には、DeferredTask はシリアライズされて TaskQueue に突っ込まれ、内部的にデシリアライズされて run()
されています。
そのため、内部クラスで実装すると、Serializable でないと思われる親クラスへの参照を持ってしまうため、正常に動きません。(多分)
同様の理由で、匿名クラスでの実装も出来ません。文法的には一番便利なのですが…
上記の理由により、親クラスの内部プロパティや、今のメソッドスコープの変数に依存した実装は出来ません。
要は、必要な情報は全て DeferredTask インスタンスに渡してあげてください。
便利な分、シリアライズの面で取り扱いが難しくなっています。この点を注意し、DeferredTask は気軽なタスクで利用しましょう。
TaskQueue について便利情報
○ 秒後とかしたければ countdownMillis(long)
を使う。
final TaskOptions option = TaskOptions.Builder
.withPayload(new SomeTask("someparamvalue"))
.countdownMillis(10000); // 10 秒後
taskName(String)
を使えば TaskQueue 管理画面に名前が出ます(多分)
final TaskOptions option = TaskOptions.Builder
.withPayload(new SomeTask("someparamvalue"))
.taskName("SomeTask");