web-dev-qa-db-ja.com

サービスをアクティビティまたはフラグメントにバインドしますか?

音楽プレーヤーアプリを開発しています。私は複数のフラグメントを持つメインアクティビティを持っており、それぞれがデバイスアルバム、アーティストなどで曲を表示しています。
私はすべての再生およびその他のものを処理する音楽サービスを持っています。
混乱しているのは、このサービスとさまざまなフラグメントのバインディングです。
今、私はメインアクティビティと各フラグメントを個別にサービスとバインドしており、かなりうまく機能しています。しかし、これが本当にベストプラクティスかどうか疑問に思いました。メインアクティビティをサービスにバインドし、それを子フラグメントで使用する方法はありますか?
アクティビティやフラグメント、サービスの非常に基本的な概念が欠けている可能性があります。だから誰かがこの点で私を導いてください。
これは概念的な質問のほうが多いので、コードは必要ありません。それでも必要な場合はお知らせください。

編集:
私の質問は次のとおりです。複数の子フラグメント(それぞれがサービスを使用する)を持つアクティビティとサービスをバインドするより良い方法は何ですか?

21
Anjani

ServiceではなくFragmentをアクティビティにバインドします。アプリケーションの説明(複数のFragmentが入れ替えられた1つのアクティビティ)は、これを最も(そして本当に唯一の)実用的なアプローチにします。

ServiceActivityにバインドすると、そのライフサイクルはActivityのライフサイクルに結び付けられます。 Bound Services 」を参照してください。アクティビティでFragmentを追加または削除するたびに、Fragmentが作成および破棄されます。新しいフラグメントが作成または破棄されるたびにサービスを作成および破棄する必要があるため、このプロセスにサービスをリンクしようとするのは望ましくありません。

代わりに、ホストActivityにバインドします。次に、バインドされたサービスにアクセスするためのインターフェースを使用して、またはIntentによって、フラグメントからのホストアクティビティと対話できます。

18
Rarw

よりクリーンなアーキテクチャは、フラグメントから直接バインドすることだと思います。 Rarwの回答で概説されている問題に関しては、アクティビティとフラグメントからサービスにバインドすることもできます。このようにして、アクティビティが破棄されなくなるまでサービスが存在することを確認します。

フラグメントから接続することには、2つの主な利点があります。

  1. サービス接続は非同期であるため、フラグメント内では、アクティビティから取得しているサービスがnullでないことを実際に確信することはできません。これにより、少なくともいくつかのnullポインターチェックと、フラグメントが作成されたときとサービスが接続されたときの両方でフラグメントを更新するメカニズムにつながります(そのため、どちらが先に発生してもデータを表示することが確実です)。

  2. フラグメントが存在する特定のアクティビティには依存しません。アクティビティからサービスを取得するには、アクティビティ固有のクラスへのキャストを行っていると思います。サービスを取得するためにBoundActivityのようなメソッドを使用してgetBoundServiceのようなインターフェイスを作成することもできますが、ポイント1の利点を考慮するとオーバーヘッドになると思います。複数のサービスがある場合はどうでしょうか。

[〜#〜]更新[〜#〜]

これは、これを示す非常に単純なプロジェクトです。 https://github.com/ena1106/FragmentBoundServiceExample

17
Ena

信頼できることがわかった唯一の方法は、[Fragmentでローダーを使用することです。

  1. フラグメントにLoaderを作成します
  2. contextLoaderを使用(フラグメントのactivityが呼び出されたときにinitLoaderonCreateに設定)
  3. サービスがバインドされるとすぐにforceLoad()を呼び出すonStartLoadingを使用して、ServiceConnectionでサービスをバインドします
  4. オプションでonStartLoading/onStopLoadingにコールバックを登録します
  5. onStopLoadingのサービスをアンバインドします
0
junique

このライブラリ、イベントバスパブリッシュ/サブスクライブパターンでイベントバスパターンを使用してトレイを作成できます。 https://github.com/greenrobot/EventBus 詳細については、プロジェクトサイトを確認してください。

イベントをサービスとの間で、アクティブまたはフラグメントに送信できます

0
ingyesid

フラグメントのライフサイクルの初めにサービスからフラグメントにデータを取得する必要がある場合、主にデバイスをローテーションするときに、onServiceConnected onアクティビティをまだ呼び出すことができず、NPEを取得します。サービスはbindService()ではなくstartService()で開始されるため、フラグメントに独自の接続を確立させるのは良い考えだと思います。

0
Informatheus

getActivity()を使用すると、フラグメントからアクティビティにアクセスできます

私のホストアクティビティでサービスをバインドし、引数で設定されたバンドルによってIbinderのオブジェクトを渡します。

そして私のコードはこれを好きかもしれません:

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //put service in bundle
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};
0
fantianwen