It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

【Android】Serviceをつかってみる

バックグラウンドで動くプログラムServiceを使ってみました。

Serviceの使用方法

Serviceの起動方法には、

  • startService()を使用
  • bindService()を使用

の大きく分けて2種類があります。

Service起動方法の違い

起動方法による違いは、以下のとおりです。

startService

  • Service起動中は、ActivityへIntentの発行が可能。
  • Service起動後は、ActivityからServiceを制御する経路がない。
  • Serviceの生存期間はActivityに依存しない。明示的にstopServiceが呼ばれるまで動き続ける。

bindService

  • バインドを使うことでActivityからServiceを制御できる。
  • Serviceの生存期間はコネクションに依存。コネクションが切断されるとServiceは終了する。

startService()を使用した起動

startService()を使用して、Serviceを起動した時のライフサイクルを以下に記載します。

順序 メソッド 説明
1 onCreate() Serviceが初回作成時に呼ばれる。
2 onStartCommand() クライアントが明示的にstartService(Intent)を呼び出したタイミングで呼ばれる。
このメソッドを直接呼び出してはいけない。
APIレベル5以前は、onStart()が使用されるため注意。
3 onDestroy() Serviceが使用されなくなったタイミングで呼ばれる
Serviceの持っているリソースをクリーンアップする。

サンプルソース

■ AndroidManifest.xml

<service android:name="Service名" />

■ Activityの呼び出し

public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button startButton = (Button) findViewById(R.id.startService);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Serviceの起動
                Intent intent = new Intent(MainActivity.this, MyService.class);
                startService(intent);
            }
        });
        
        Button stopButton = (Button) findViewById(R.id.stopService);
        stopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Serviceの停止
                Intent intent = new Intent(MainActivity.this, MyService.class);
                stopService(intent);
            }
        });
    }
}

■ Serviceクラス

public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("service", "onCreate");
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("service", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Override
    public void onDestroy() {
        Log.d("service", "onDestroy");
        super.onDestroy();
    }
}

bindService()を使用した起動方法

bindService()を使用して、Serviceを起動した時のライフサイクルを以下に記載します。

順序 メソッド 説明
1 onCreate() Serviceが初回作成時に呼ばれる。
2 onBind() Service接続時に呼ばれる。ServiceとActivityを仲介するIBinderを返却する。
3 ServiceConnection#
onServiceConnected()
Service接続後、Binderが確立したタイミングで呼び出される。
4 unBind() クライアントがServiceと切断されたタイミングで呼ばれる。
5 onDestroy() Serviceが使用されなくなったタイミングで呼ばれる。
Serviceの持っているリソースをクリーンアップする。

ServiceをbindService()経由で呼び出す場合は、インタフェースとしてServiceConnectionを使用します。
ServiceConnectionによって取得するIBinderを介することで、Serviceへの制御を行うことが可能です。

サンプルソース

■ AndroidManifest.xml

<service android:name="Service名" />

■ Activityの呼び出し

public class MainActivity extends Activity {

    // Serviceとのインターフェースクラス
    private ServiceConnection mConnection = new ServiceConnection() {
        BindService mBindService;
        public void onServiceConnected(ComponentName className, IBinder service) {
            // Serviceとの接続確立時に呼び出される。
            // service引数には、Onbind()で返却したBinderが渡される
            mBindService = ((BindService.LocalBinder)service).getService();
            //必要であればmBoundServiceを使ってバインドしたServiceへの制御を行う
        }
     
        public void onServiceDisconnected(ComponentName className) {
            // Serviceとの切断時に呼び出される。
            mBindService = null;
        }
    };

    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button bindButton = (Button) findViewById(R.id.bindtService);
        bindButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Serviceをbindする
                Intent i = new Intent(MainActivity.this,BindService.class);
                bindService(i, mConnection, Context.BIND_AUTO_CREATE);
            }
        });
        
        Button unbindButton = (Button) findViewById(R.id.unbindService);
        unbindButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Serviceをunbindする
                unbindService(mConnection);
            }
        });
    }
}

■ Serviceクラス

public class BindService extends Service {
 
    // Serviceに接続するためのBinderクラスを実装する
    public class LocalBinder extends Binder {
        //Serviceの取得
        BindService getService() {
            return BindService.this;
        }
    }

    // Binderの生成
    private final IBinder mBinder = new LocalBinder();
    
    @Override
    public IBinder onBind(Intent intent) {
        // Service接続時に呼び出される
        // 戻り値として、Serviceクラスとのbinderを返す。
        Log.i("", "onBind" + ": " + intent);
        return mBinder;
    }
 
    @Override
    public void onRebind(Intent intent){
        // Unbind後に再接続する場合に呼ばれる
        Log.i("", "onRebind" + ": " + intent);
    }
 
    @Override
    public boolean onUnbind(Intent intent){
        // Service切断時に呼び出される
        //onUnbindをreturn trueでoverrideすると次回バインド時にonRebildが呼ばれる
        return true;
    }
}

参考

http://www.techdoctranslator.com/android/guide/services/bound-services
http://yuki312.blogspot.jp/2012/07/androidserviceonstartcommand.html
http://techbooster.org/android/application/3270/