Service bind で注意すべきこと

Service をバインドして注意しなければならないのは、bindService の実行と
実際に Service メソッドcall 可能になるのは非同期ということである。

よくサンプルで見かける形、

ServiceConnection インスタンス生成時に定義生成しておいて、

------------- Client 側 ---------------
SampleService service;

protected ServiceConnection mConnection = new ServiceConnection(){
   @Override
   public void onServiceConnected(ComponentName className, IBinder service){
      service = ((SampleService.MyServiceLocalBinder)service).getService();
   }
   @Override
   public void onServiceDisconnected(ComponentName className){
      service = null;
   }
};
------------- Service側 ---------------
public class SampleService extends Service{
   private final IBinder mBinder = new MyServiceLocalBinder();

   @Override
   public IBinder onBind(Intent intent){
      return mBinder;
   }
   class MyServiceLocalBinder extends Binder{
      public SampleService getService(){
         return SampleService.this;
      }
   }



---------------------------------------
サービス生成後、上の ServiceConnection を指定してバインドをする。
bindService(new Intent(context,SampleService.class),mConnection,Context.BIND_AUTO_CREATE);


注意すべきは、bindService 直後にService側のメソッドを call してはNGである。
まだ、service は NULL のため、NullPointerException 発生する。

Service側のメソッドを call したい時に、bindService を実行することにして
onServiceConnected の中でService側のメソッドを実行して直後不要ならバインドをすぐに切断する。
修正すると、、、

protected ServiceConnection mConnection = new ServiceConnection(){
   @Override
   public void onServiceConnected(ComponentName className, IBinder service){
      service = ((SampleService.MyServiceLocalBinder)service).getService();
      // SampleService のメソッド実行

      // 切断
      unbindService(mConnection);

   }
   @Override
   public void onServiceDisconnected(ComponentName className){
      service = null;
   }
};