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(); // サービスは必要ないので終了させる。
    }

そのまんまっちゃそのまんまッスね。これでなんとなく理解できたのかな。別途木南さん本を確認してみます。参考にしたのは以下のコンテンツです。