Service bind を簡潔にする(AIDL不使用で)

先日 Service をバインドして呼びだす方法を以下2つのインターフェースを使用して
バインドを実行、呼び出し側を簡単に記述することができましたが。。。

import android.app.Service;
import android.os.IBinder;
/**ITransitBinder */
public interface ITransitBinder extends IBinder{
   public Service getService();
}

----------------
public interface IServiceProcessor<T extends android.app.Service>{
   public void process(T service);
}

----------------

Service
 クラスも、onBind / onUnbind / onRebind がほとんど実装で
記述することがないのであれば、基底のクラスを用意をしても良いと思った。
使いまわす基底のServiceクラス が、
  onCreate / onStartCommand / onDestroy 
の記述に注力できるからだ。


import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
/**
 * BaseService
 */

public abstract class BaseService extends Service{
   private final IBinder mBinder = new MyServiceBinder();

   class MyServiceBinder extends Binder implements ITransitBinder{
      @Override
      public Service getService(){
         return BaseService.this;
      }
   }
   @Override
   public final IBinder onBind(Intent intent){
      onBindSuport(intent);
      return mBinder;
   }
   @SuppressWarnings("unused")
   public void onBindSuport(Intent intent){
      // onBind をオーバライド禁止にする代わりに
      // このメソッドをオーバライド許可する。
   }


   @Override
   public void onRebind(Intent intent){
   }
   @Override
   public boolean onUnbind(Intent intent){
      // 次回バインド時は、onRebind を実行
      return true;
   }
}
------------------------------------
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
/**
 * ServiceClient
 */

public final class ServiceClient{
   Context mContext;
   private Class<? extends Service> mServiceClass;
   Service mBoundService;
   IServiceProcessor mProcessor;

   public ServiceClient(Context context, Class<? extends Service> serviceClass){
      mContext = context;
      mServiceClass = serviceClass;
   }

   public void execute(IServiceProcessor processor){
      mProcessor = processor;
      mContext.bindService(new Intent(mContext,mServiceClass), mConnection, Context.BIND_AUTO_CREATE);
   }

   ServiceConnection mConnection = new ServiceConnection(){
      @SuppressWarnings("unchecked")
      @Override
      public void onServiceConnected(ComponentName name,IBinder binder){
         mBoundService = ((ITransitBinder)binder).getService();
         mProcessor.process(mBoundService);
         mContext.unbindService(mConnection);
      }
      @Override
      public void onServiceDisconnected(ComponentName name){
         mBoundService = null;
      }
   };
}
----------------------
この2つのインターフェースと2つのクラスがあれば、とても楽になる。

例)

public class SampleService extends BaseService{
   @Override
   public void onCreate(){

   }
   @Override
   public int onStartCommand(Intent intent,int flags,int startId){

      return START_STICKY;
   }
   @Override
   public void onDestroy(){

   }
   // クライアントから呼ばれるメソッド
   public void function(int value){

   }
}

Activity で、上記、SampleService のメソッド呼び出し

ServiceClient serviceClient = new ServiceClient(getApplicationContext(),SampleService.class);
serviceClient.execute(new IServiceProcessor<SampleService>(){
   @Override
   public void process(SampleService service){
      // SampleService のメソッドを呼ぶ。
      service.function(1);
   }
}
);