KitchenTimerService
再度整理を試みてみます。
何をしてるか整理
Main という Activity を中心に確認してみます。まずサービス開始の部分ですが、Main の onCreate() にて以下。
Intent intent = new Intent(this, KitchenTimerService.class); startService(intent); IntentFilter filter = new IntentFilter(KitchenTimerService.ACTION); registerReceiver(receiver, filter);
- Service のサブクラスのクラス (KetchenTimerService.class) を渡して Intent を生成してそれを startService() 手続きに渡すことでサービスが開始される模様
- Service.ACTION を渡して IntentFilter を生成
- 上記で生成した IntentFilter なオブジェクトと BroadcastReceiver のサブクラス (KitchenTimerReceiver) のオブジェクトを registerReceiver() 手続きに渡す
- これで KitchenTimerService が ACTION な Intent を投げたら BroadcastReceiver なサブクラスの onReceive() が受ける形になるはず
で、次のバインドです。これも材料無しで整理を試みてみます。上記のコードの直下に以下な記述。
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
intent が指すオブジェクトは KitchenTimerService.class なナニをオブジェクト生成時に渡してます。ここでは KitchenTimerService#onBind() が呼び出される模様。定義は以下。
public IBinder onBind(Intent intent) { Toast toast = Toast.makeText(getApplicationContext(), "onBind()", Toast.LENGTH_SHORT); toast.show(); return new KitchenTimerBinder(); }
toast を show して KitchenTimerBinder のオブジェクトを戻してます。KitchenTimerBinder クラスは KitchenTimerService の中でクラス定義されてて以下。
class KitchenTimerBinder extends Binder { KitchenTimerService getService() { return KitchenTimerService.this; } }
getService というメソドが定義されてますな。KitchenTimerService なオブジェクトを戻す形になっております。
で、ここからは完全に類推なんですが、bindService() 手続きに渡している serviceConnection ですが、Main のクラス定義内で定義されてて以下です。
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { kitchenTimerService = ((KitchenTimerService.KitchenTimerBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName className) { kitchenTimerService = null; } };
この ServiceConnection というクラスのオブジェクトは bindService() に渡すことで、サービスへの接続時および切断時に呼ばれるコールバックが記述されている模様。
接続時に、onBind() が戻す IBind なオブジェクトを onServiceConnected() に渡していると類推してます。
で、Main クラスの属性である kitchenTimerService に KitchenTimerBinder#getService() メソドによって戻されたオブジェクトが格納される模様。
これでサービスとクライアントが情報をやりとりする事ができるようです。いったん切り離して云々は現時点ではスルーします。
後は
Service 側で
sendBroadcast(new Intent(ACTION));
として差し上げる事で、BroadcastReceiver#onReceive() が呼び出される訳ですな。ちなみにこのケースではサービス側とクライアント側のプロセスが同一なので、面倒な事をしなくても良い模様。
後始末
サンプルでは Main#onDestroy() で処理している模様。
public void onDestroy() { super.onDestroy(); unbindService(serviceConnection); // バインド解除 unregisterReceiver(receiver); // 登録解除 kitchenTimerService.stopSelf(); // サービスは必要ないので終了させる。 }
そのまんまっちゃそのまんまッスね。これでなんとなく理解できたのかな。別途木南さん本を確認してみます。参考にしたのは以下のコンテンツです。