サービス(Service)とはアクティビティ(Activity)のように常に前面に出ないで,裏で動くプログラムである。いわゆる常駐プログラムのことで,WindowsでいうところのサービスやLinuxのデーモンと同じように考えるとわかりやすい。
Androidでは,プロセスの終了はOS任せであることは以前にも説明したが(第309話 アクティビティの状態遷移),裏に引っ込んだアクティビティは他のプロセスを実行するために,Killされてしまうことがある。それに対し,サービスは勝手にKillされることがない。
上図がサービスの状態遷移である。状態遷移といっても,アクティビティのように隠れたり,復活したりしないので単純である。起動したら,終了するまで実行中なのだ。気になる点は,onCreateメソッドは1回しか呼び出されないのに,なぜ,onStartメソッドは何回も呼びされるのかである。
サービスは裏に引っ込んでも,実行されているため,同じサービスを何度も起動してしまうことがある。でもCreateされるのは1回こっきりであり,同じサービスのonStartメソッドが何度も呼び出されるのである。 サービスを起動するのは,アクティビティである。画面を定義するXMLファイルにボタンを記述して,クリックしたらサービスを起動するように以下のようにコードを書く。
-------------------------------------------------------------- Intent intent = new Intent(this, SimpleService.class); startService(intent); --------------------------------------------------------------
Intentを作成して,startServiceでサービスを開始する。
サービスはServiceクラスを継承する。
-------------------------------------------------------------- public void onCreate() { Toast.makeText( this,R.string.create_message,Toast.LENGTH_SHORT).show(); } --------------------------------------------------------------
最初に呼び出されるonCreateメソッドではToastでcreate_messageを出力している。create_messageはstring.xml内で,以下のように定義している。
-------------------------------------------------------------- <string name="create_message">作成します!</string> <string name="start_message">開始します!</string> <string name="stop_message">終了します!</string> --------------------------------------------------------------
だから,サービスの起動直後は上のように表示されるのだ。
-------------------------------------------------------------- public void onStart(Intent intent,int StartId) { Toast.makeText( this,R.string.start_message,Toast.LENGTH_SHORT).show(); Thread t = new Thread() { @Override public void run() { try { Thread.sleep(10 * 1000); stopSelf(); } catch (InterruptedException e) { } } }; t.start(); } --------------------------------------------------------------
onStartメソッドでは,start_messageを表示後,Thread(スレッド)を開始している。10 * 1000ミリ秒後,つまり10秒後にstopSelfでサービスを終了する。
上がstart_messageのToast表示の画像である。メッセージ表示後,続けて何度もStart Serviceのボタンを押すと,押した回数分だけ「開始します!」と表示されるが,「作成します!」は表示されない。
-------------------------------------------------------------- public void onDestroy() { Toast.makeText( this,R.string.stop_message,Toast.LENGTH_SHORT).show(); } --------------------------------------------------------------
では,onDestroyでstop_messageを以下のように表示するのは,どの時点から10秒後なのか?
Start Serviceボタンを例えば,等間隔で押し続けていても,「終了します!」というメッセージは最初にボタンを押してから,約10秒後に表示された。ゆえに,最初のStartに対応していることがわかる。