最終更新:2016-09-29 (木) 17:00:40 (2432d)
Android/サービス
バックグラウンドで長時間動作して作業を行い、ユーザー インターフェースを表示しないアプリケーション コンポーネント
http://developer.android.com/intl/ja/guide/components/services.html
http://developer.android.com/reference/android/app/Service.html
概要
- Service はバックグラウンドで長時間動作して作業を行うコンポーネントで、ユーザインターフェイスは提供しません。別のアプリケーションコンポーネントがサービスを開始することができ、ユーザが別のアプリケーションに切り替えたとしてもバックグラウンドでその実行が継続することになります。さらに、コンポーネントはサービスにバインドして双方向にやり取りし、さらにプロセス間通信 ( IPC ) を行うことができます。例えば、ネットワークのトランザクション、音楽再生、ファイル I/O の実行、またはコンテンツプロバイダなど、すべてをバックグラウンドでハンドルして構いません。
スレッド
- サービスは、そのホスト プロセスのメインスレッドで実行します。
- サービスが自身のスレッドを作成することはなく、別のプロセスで実行されることもありません(別の方法を指定しない限り)。
- つまり、サービスが CPU を集中的に使ったり、ブロック操作を行ったりするような場合(MP3 の再生やネットワーク作業)は、サービス内に新しいスレッドを作成してその作業を行う必要があります。
- 別のスレッドを使うことで、「アプリケーションが応答していません (ANR)」のエラーが発生するリスクを軽減でき、アプリケーションのメインスレッドをアクティビティのユーザー操作専用にすることができます。
通信
- サービスの実行中は、サービスからクライアントに対しては、自由にIntentをブロードキャストして、クライアント側で動作を行わせることができます。
- しかし、クライアントからサービスに対しては、「バインド」という仕組みを使用しなければ、サービス側の処理を動作させることができません。
関連クラス
- Context - android.content.Context
- Service - android.app.Service
- IntentService? - android.app.IntentService
メモ
- サービスはActivityとは異なり、同一のサービスが複数起動することはありません。
- 起動していない状態から「startService()」を呼び出すと、「onCreate()」が呼び出されます。もし、対象のサービスがすでに起動している場合は、onCreate()は呼び出されません。
種類
Android/ローカルサービス
- 同じプロセス内。
Android/リモートサービス
- 違うプロセス。AIDLが必要
動作
- Context.startServiceで開始(無期限に実行)する方法と、Context.bindServiceで開始する方法がある
- サービスは開始されるのと(無期限に実行させるために)と同様にバインドされることも許可し、両方の方式で動作させることができます。
- これは単にふたつのコールバックメソッドを実装するかどうかの話で、Service.onStartCommand() はコンポーネントがサービスを開始することを許可し、Service.onBind() はバインドすることを許可します。
Android/開始されたサービス
- 開始
- 終了
- Context.stopService
- Service.stopSelf?()
- 一旦開始されると、たとえ開始したコンポーネントが破棄されても、サービスは無期限に実行できます。
- 通常、開始されたサービスは 1 つの操作を実行するだけで、呼び出し元に結果を返すことはありません。
- サービス起動後はActivityからServiceを制御する経路がない
- Service全般として実行中はServiceからActivityへIntentの発行が可能
- たとえば、サービスはネットワーク上でファイルのダウンロードやアップロードを行います。
- 操作が完了すると、サービスは自身で停止する必要があります。
- Serviceの生存期間はActivityに依存しない。明示的にstopServiceが呼ばれるまで動き続ける。
- コンポーネントが startService() を呼び出してサービスを開始すると、stopSelf() を使ってサービス自身が停止するか、他のコンポーネントが stopService() を呼び出して停止するまで、サービスは実行し続けます
- 通常、開始されたサービスは 1 つの操作を実行するだけで、呼び出し元に結果を返すことはありません。
呼び出し順
Android/バインドされたサービス
- Context.bindService/Context.unbindService?
- バインド(bind)という仕組みを使い、ActvitiyとServiceでコネクションを確立する(接続する)
- バインドを使うことでActivityからServiceを制御できる
- Serviceの生存期間はコネクションに依存。コネクションが切断されるとServiceは終了する。
呼び出し順
両方
- startServiceメソッドとbindServiceメソッドが混在して実行した場合、unbindServiceをしても、Serviceオブジェクトがdestroyされることは無い
フォアグラウンド実行
- フォアグラウンドのサービスは、ユーザが積極的に意識するものとして考えられ、それゆえにメモリ残量が少なくなった際のシステムによる強制終了の候補にはなりません
- フォアグラウンドのサービスはステータスバーに通知を提供する必要があり、サービスは "継続中" にあるという位置付けになり、これはサービスが停止されるかフォアグラウンドから除去されない限りは、通知を片付けることができないということを意味します。
- Service.startForeground
イベント
- Service.onCreate - サービス生成時に呼び出される
- Service.onStartCommand - Context.startService時に呼び出される。複数回サービスを起動した場合、このメソッドは複数回呼び出される
- Service.onStart?はdeprecated
- Service.onDestroy - サービスの破棄時に呼び出される
- Service.onBind - Context.bindService時に呼び出される
- Service.onRebind?
- Service.onUnbind?
サービスの複数起動
- サービスはActivityとは異なり、同一のサービスが複数起動することはありません。
- 起動していない状態から「Context.startService()」を呼び出すと、「Service.onCreate()」が呼び出されます。もし、対象のサービスがすでに起動している場合は、Service.onCreate()は呼び出されません。
メモ
- サービスの実行中は、サービスからクライアントに対しては、自由にIntentをブロードキャストして、クライアント側で動作を行わせることができます。しかし、クライアントからサービスに対しては、「バインド」という仕組みを使用しなければ、サービス側の処理を動作させることができません。
終了されにくくする
- Android/フォアグラウンドサービスにする
- onStartCommandで強制終了後の動作を設定
サービスの登録
- AndroidManifest.xmlに記述する
Android/システムサービス
- Context.getSystemServiceで取得できる
AndroidManifest.xml
- Each service class must have a corresponding <service> declaration in its package's AndroidManifest?.xml.
<service android:name=".サービス名" />
Android/通知
関連
参考
http://www.atmarkit.co.jp/fsmart/articles/android07/android07_1.html
http://www.atmarkit.co.jp/fsmart/articles/android31/01.html
http://www.atmarkit.co.jp/ait/articles/0906/18/news102.html
http://techbooster.jpn.org/andriod/application/3270/#more-3270
http://android.boo.jp/contents/Framework/ManagerService01.html