こことここで(部分的に、私の心に)対処された厄介な質問をしています。多くの例のように、(たとえば) 1 つのアクティビティとサービスを使用して、音楽アプリケーションを作成したいとしましょう。アクティビティが停止または破棄されたときに、サービスを持続させたいと考えています。この種のライフサイクルは、開始されたサービスを示唆しています。
サービスは、アプリケーション コンポーネント (アクティビティなど) が startService() を呼び出してサービスを開始したときに「開始」されます。サービスが開始されると、それを開始したコンポーネントが破棄された場合でも、サービスは無期限にバックグラウンドで実行できます。
わかりましたが、サービスと通信できるようにしたいので、サービス バインディングが必要です。この回答が示唆するように、バインドされたサービスと開始されたサービスの両方があります。
- アクティビティの開始時 (またはその他の時点) にstartService()を呼び出します。
- その後、bindService()を呼び出してIBinderインターフェイスを取得し、そこから処理を進めます。
ここまでは順調ですが、サービスが開始された時点で、サービスが存在するかどうかわからないという問題が発生します。開始されているか、開始されていない可能性があります。答えは次のようになります。
- 起動時に、サービスへのバインドを試みます ( BIND_AUTO_CREATEフラグなしでbindService()を使用します)。
- それが失敗した場合は、 を使用してサービスを開始し
startService()
、それにバインドします。
このアイデアは、次のドキュメントの特定の読み取りを前提としていbindService()
ます。
アプリケーション サービスに接続し、必要に応じて作成します。
ゼロフラグが「サービスは本当に必要ない」ことを意味する場合は、問題ありません。そこで、次のコードを使用してこのようなことを試みます。
private void connectToService() {
Log.d("MainActivity", "Connecting to service");
// We try to bind to an existing service
Intent bindIntent = new Intent(this, AccelerometerLoggerService.class);
boolean bindResult = bindService(bindIntent, mConnection, 0);
if (bindResult) {
// Service existed, so we just bound to it
Log.d("MainActivity", "Found a pre-existing service and bound to it");
} else {
Log.d("MainActivity", "No pre-existing service starting one");
// Service did not exist so we must start it
Intent startIntent = new Intent(this, AccelerometerLoggerService.class);
ComponentName startResult = startService(startIntent);
if (startResult==null) {
Log.e("MainActivity", "Unable to start our service");
} else {
Log.d("MainActivity", "Started a service will bind");
// Now that the service is started, we can bind to it
bindService(bindIntent, mConnection, 0);
if (!bindResult) {
Log.e("MainActivity", "started a service and then failed to bind to it");
} else {
Log.d("MainActivity", "Successfully bound");
}
}
}
}
そして、毎回成功したバインドが得られます。
04-23 05:42:59.125: D/MainActivity(842): Connecting to service
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it
04-23 05:42:59.134: D/MainActivity(842): onCreate
グローバルな質問は、「バインドされたサービスと開始されたサービス、およびそれらの使用方法を誤解していませんか?」です。より具体的な質問は次のとおりです。
- 渡されたゼロフラグが
bindService()
「サービスを開始しない」ことを意味すると考えるのは、ドキュメントの正しい理解ですか?bindService()
そうでない場合、サービスを開始せずに呼び出す方法はありませんか? - サービスが実行されていなくてもが
bindService()
戻るのはなぜですか? この場合、呼び出しtrue
に基づいて、サービスが開始されたようには見えません。Log
- 前のポイントが の正しい/予期される動作で
bindService()
ある場合、回避策はありますか (つまりstartService
、サービスが実行されていない場合にのみ が呼び出されるようにしますか?)
PS私は自分のコードの問題から離れました:startService()
繰り返しstartService()
は単に無視されるので、関係なく呼び出しを発行します。しかし、私はまだ問題をよりよく理解したいと思っています。