web-dev-qa-db-ja.com

Androidのアクティビティへのサービスのバインド

RTSPを使用してストリーミングオーディオを再生するシンプルなメディアプレーヤーを作成しようとしています。 GUIアクティビティと、再生を実行するサービスがあります。私の質問は、アクティビティとサービスの間の最適な通信方法です(たとえば、プレーヤーの状態に基づいてGUIを更新する)。

OnBind()を使用してサービスをアクティビティにバインドできることは知っていますが、正しく理解すれば、アクティビティが強制終了されるとサービスが停止します。ユーザーがアクティビティを終了しても、再生を継続したい。この問題に対処する標準的な方法または推奨される方法はありますか?

86
aspartame

「Android startService(..)でサービスを開始すると、そのサービスは明示的にstopService(..)を呼び出すまで実行されます。サービスを実行できる理由は2つあります誰かがContext.startService()を呼び出すと、システムはサービスを取得し(サービスを作成し、必要に応じてonCreate()メソッドを呼び出します)、その後、引数を指定してonStartCommand(Intent, int, int)メソッドを呼び出しますこの時点で、サービスはContext.stopService()またはstopSelf()が呼び出されるまで実行を続けますContext.startService()への複数の呼び出しはネストしません(ただし、 onStartCommand()に対応する呼び出し)であるため、Context.stopService()またはstopSelf()が呼び出されると、サービスは何度起動されても停止しますが、サービスはstopSelf(int)メソッドは、開始されたインテントが処理されるまでサービスが停止されないようにします。

クライアントは、Context.bindService()を使用してサービスへの永続的な接続を取得することもできます。同様に、サービスがまだ実行されていない場合(実行中にonCreate()を呼び出す)、サービスを作成しますが、onStartCommand()を呼び出しません。クライアントは、サービスがonBind(Intent)メソッドから返すIBinderオブジェクトを受け取り、クライアントがサービスにコールバックできるようにします。接続が確立されている限り、サービスは実行され続けます(クライアントがサービスのIBinderの参照を保持するかどうか)。通常、返されるIBinderは、AIDLで記述された複雑なインターフェイス用です。

サービスは開始でき、接続をバインドできます。このような場合、システムは、開始されるか、Context.BIND_AUTO_CREATEフラグを使用して1つ以上の接続がある限り、サービスを実行し続けます。これらの状況のどちらも成立しない場合、サービスのonDestroy()メソッドが呼び出され、サービスは事実上終了します。すべてのクリーンアップ(スレッドの停止、レシーバーの登録解除)は、onDestroy()から戻ったときに完了する必要があります。

148
Schildmeijer

まず、理解する必要がある2つのこと

クライアント

  • 特定のサーバーにリクエストを送信します

    bindService(new 
        Intent("com.Android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

ここでmServiceConnServiceConnection class(inbuilt)のインスタンスです。実際には、ネットワーク接続状態を監視するための2つのメソッド(ネットワーク接続用と非接続用)を実装する必要があるインターフェースです。

サーバ

  • クライアントのリクエストを処理し、リクエストを送信するクライアント専用のレプリカを作成します。サーバーのこのレプリカは異なるスレッドで実行されます。

クライアント側で、サーバーのすべてのメソッドにアクセスする方法は?

  • サーバーは、IBind Object.soを使用して応答を送信します。IBindオブジェクトは、(。)演算子を使用してサービスのすべてのメソッドにアクセスするハンドラーです。

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

今、サービスにあるメソッドを呼び出す方法

myservice.serviceMethod();

ここでmyServiceはオブジェクトであり、serviceMethodeはサービスのメソッドです。この方法により、クライアントとサーバー間で通信が確立されます。

22
Hardik Gajera

電話しようとした

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

その結果、スティッキーサービスを作成してバインドできました。 バウンドサービスの例 の詳細なチュートリアル。

10
M.Hefny

nbindService というメソッドがあり、bindServiceの呼び出し時に作成したServiceConnectionを取得します。これにより、サービスを実行したままサービスから切断できます。

アクティビティを再度開始すると、おそらく実行中かどうかわからないため、再度接続すると問題が発生する可能性があります。そのため、アクティビティコードでそれを考慮する必要があります。

幸運を!

5
vrutberg