多分いろいろな実装方法があると思いますし、処理の特性によって最適な方法は
異なるかもしれませんが、私が一番簡単じゃないかなと思っている方法を述べます。
デベロッパーの方、情報交換させてくれませんか。
「おれ(わたしは)こうやってる」などのアイディアや「こうした方がいいんじゃないか」
といった観点があれば是非教えて貰えるとうれしいです。
・息の長いThreadよりonStartとAlarmManagerを使う
どちらも試しましたが、後者の方がコードが簡潔になりますし、バグが混入しに
くいような気がします
・onStartから作業用Thread(Task)を起こす
onStartで時間をかけすぎると(多分5秒以上)怒られるので、時間がかかる場合
は別スレッドで行い、onStartは直ちに終わるようにしています。ちなみに生Thread
よりもjava.util.concurrent.ExecutorServiceなどを使ったほうが簡単かもしれません。
例外の取り方に癖があるので気をつけます。
(http://java.sun.com/javase/ja/6/docs/ja/api/java/util/concurrent/Callable.html)
・定期的に処理を行う場合は、作業用Threadの処理終了時にAlarmをset
作業用Threadは、一回処理をして終わるようにします。定期的に処理したい場合は
Threadが終わる時にAlarmに登録します。
・止める処理もonStart
止めるときの処理もonStartでやるのがいいような気がします。intentのActionで
振舞いを分けるイメージです。以下のような感じです。止める時も呼び側がstartServiceメソッド
になってしまうのが少し誤解を招きそうですが、僕はこうしています。
public void onStart(final Intent intent, int startId) {
super.onStart(intent, startId);
if (ACTION_EXECUTE.equals(intent.getAction())) {
// スレッド起こして処理実行
}
else if (ACTION_STOP.equals(intent.getAction()) ){
// 終了処理(Alarmのキャンセルなど)
}
・・・
}
もちろんバインドして終了処理を呼ぶ方法もありだと思います。
・必要に応じてwakelockを使う
Alarmはpartial wakelockを取得してないとスリープ時に呼ばれないことがあるようです。
またwifiなどもスリープする可能性があるので、処理の特性に応じて適宜最小限の
wakelockをかけます。
・・・ところで、Androidにはちょっと厄介な特性があります。それは、メモリが
足りないなどの諸々の理由でServiceが勝手に殺されることがあるということです。
・onLowMemoryは期待しない
メモリが少なくなるとonLowMemoryメソッドが呼ばれます。このメソッドをうまく
活用すればよいのですが、あまり役に立ちません。なぜなら、このメソッドは
ちょっとしたことですぐに呼ばれるからです。
・onDestroyも期待しない
じゃ、死ぬときにonDestroyが呼ばれると思いきや、呼ばれずに死ぬことの方が
多いです。なので、ここにコードを書いてもあまり意味はありません。
・各処理の終了時に現在の状況を保存しておき、onCreateで再startする
つまり死ぬことを予め予期できないし検知できないので、いつ死んでもいいように、
なんらかの処理を終えたときに最新の状況を逐次記録(永続化)しておきます。
Serviceのプロセスは殺されたとしても、しばらくするとまた別のプロセスが勝手に
生成されます。しかしこの時点ではServiceはまっさらな状態なので、以前の最新の
状況を読み込んで、何をやっていたかを思い出してから再度動き続けるようにします。
以上です。
繰り返しますが、他にもアイディアや観点があれば是非教えて貰えるとうれしいです。
------------------------------------------
EGAWA Takashi