私のアプリには、MP3 ストリームの音楽を再生するために使用されるサービスがあります。起動 (startService()) して接続 (bindService()) するので、クライアントが接続されていなくても停止しません。プレーヤーが一時停止している場合は、しばらくしてからいくつかのリソースをクリーンアップし、さらにしばらく一時停止したままになっている場合は、ほぼすべてのリソースをクリーンアップします。クライアントが接続されていない (アクティビティが接続されている) 場合は、stopSelf() を呼び出すサービスを停止します。 ; クライアントが接続されている場合は、破棄するように準備し、すべてのクライアントが切断されたときにチェックされるブール値を設定し、クライアントが接続されておらず、このブール値が true の場合は stopSelf() を呼び出します。
したがって、基本的に、サービスは (1) クライアントが接続されておらず、かつ (2) 長時間一時停止している場合にのみ破棄されます。
うまく機能していますが、問題があります。onDestroy() では、すべてのリソースを解放し、いくつかのデータ (再生されていた音楽のリストなど) を保存します。多くの音楽がある場合、ほぼ 0.5 秒かかることがあります。問題は、 onDestroy() がまだ返されていないときに、この期間に正確にアプリを再度開いたときです。何が起こるかというと、同じサービスのインスタンスが使用され、onCreate() が呼び出されないということです。なので、リソースが解放されたので、当然エラーが出ます。
このバグをシミュレートするのは非常に困難です。3回だけ再現できました。進め方がわかりません。onDestroy() からできるだけ早く戻り、別のスレッドを使用してリソースを解放し、データを保存することを考えましたが、データが保存される前に新しいサービスが開始されてしまいます。Androidでサービスの破棄/再作成が行われる方法について、誰かが詳細を知っていますか? どのクラスがそれを管理しているのかわからないため、どのコードを読めば理解を深められるかわかりません。
前もって感謝します。
アップデート:
私は自分の本当の問題を見つけました。アクティビティが切断されて再接続されたとき (すべてのアクティビティを閉じてアプリを再度開いたとき)、サービスの onBind が呼び出されていないようです。そのため、私のリソース クリーナー (プレーヤーが一時停止されたときにスケジュールされるスケジュールされたジョブ) は、クライアントが接続されていないと判断し、stopSelf() を呼び出します (onBind および onUnbind メソッドを使用して、接続されたクライアントを追跡します)。また、サービスにクライアントが接続されている場合でも、 onDestroy() が呼び出されます。次に、私のアクティビティは、すべてのリソースをクリーンアップしたばかりのサービスに接続されたままになります。
質問のタイトルも更新しました。
更新 2:
もう少し説明を加えます。アプリを閉じて再度開くと、ServiceConnection の実装のメソッド onServiceConnected が bindService の後に呼び出されますが、Service の onBind は呼び出されません。そして、クライアントが接続されていないと本当に思っているようです。ドキュメントには、開始されバインドされたサービスはすべてのクライアントがバインド解除されるまで破棄されないと書かれているにもかかわらず、破棄されるからです。