4

私は単純な音楽プレーヤーを作成しており、クライアントとバインドするAIDLインターフェイスを実装する再生サービスを作成しました。1つは単純なトラックブラウザーで、もう1つはさらに単純なプレーヤーアクティビティです。2つのアクティビティがServiceConnectionsを使用してサービスへの接続を取得している間、サービスはMediaPlayerオブジェクトを制御します。

これは、両方のアクティビティのonStart()メソッドに含まれています。

@Override
public void onStart()
{
  super.onStart();
  Intent i = new Intent(this, PureService.class);
  startService(i);
  bindService(i, mConnection, 0);
}

これは、バインドを解除してもサービスがすぐに停止しないようにするためです。もちろん、私のアクティビティがサービスからのバインド解除をまったく拒否するため、これは実際には問題ではありません。アプリケーションがこれらのアクティビティのいずれかでunbindServiceに到達すると、unbindServiceは例外なく毎回IllegalArgumentExceptionをスローします(hehe)。

onStopメソッドの場合:

@Override
public void onStop()
{
  super.onStop();

  if (mBound) {
    try {
      unbindService(mConnection);
    } catch (java.lang.IllegalArgumentException e)
    {
      //Print to log or make toast that it failed
    }
  }
  mBound = false;
}

私が疑問に思っているのはこれです:

  • onStop()メソッドでunbindService()を呼び出す必要がありますか?それともまったく?
  • 私はそれを正しく呼んでいますか?
  • 私が知っておくべきサービスを開始/バインドする方法について何か特別なことはありますか?
  • 私は完全に間違ったことをしていますか?私はAndroidプログラミングに不慣れなので、それは確かに問題外ではありません。

前もって感謝します。

編集:これがServiceConnectionのオーバーライドです

public void onServiceConnected(ComponentName className, IBinder service) {
  mBound = true;
  mService = IPureService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName arg0) {
  mBound = false;
}

プレーヤーアクティビティには追加のコードがいくつかありますが、バインディング自体とは関係ありません。

4

3 に答える 3

4

まず、実際にプロセス間でこのサービスを呼び出す必要がない限り(つまり、他の.apkから、またはandroid:processを使用して独自の.apkを何らかの理由で複数のプロセスに分割している場合)、私は本当にお勧めしますaidlの使用をやめます。利益がない場合は、より複雑になります。サービスドキュメントの「ローカルサービスサンプル」は、これを行う方法を示しています:http: //developer.android.com/reference/android/app/Service.html

第二に、開始と同時にバインドを行うことは、デザインにいくつかの基本的な欠陥があることを強く示しています。サービスの開始とサービスへのバインドは意味的に非常に異なるため、それらの異なるセマンティクスに基づいて異なる場所で実行されます。つまり、両方が実行されたとしても...実際、同じサービスで開始とバインドの両方を使用しているのは珍しい状況です。

音楽再生を行うためのサービスのクラス実装では、アクティブに再生を実行しているときにstartを使用します(したがって、ユーザーがアプリケーションのUIをアクティブに操作しなくなったときに、そのプロセスがシステムによって強制終了されることはありません)。ユーザーがUIに入ったときにサービスを開始すると、サービスの開始/停止状態が明確に定義されていないため、問題が発生する可能性があります。サービスが再生中であるか、ユーザーがたまたま入ったために開始される可能性があります。アプリのUI、そして今、それを停止する適切な時期はいつですか?これは面倒です。

バインドを解除するタイミングについては、unbindService()を以前のbindService()と常に一致させる必要があります。コードのスニペットからは、これを実行しているように見えますが、mBoundが設定されていないなどの奇妙なことがあります。実際、onStart()で一貫してバインドし、onStop()でバインドを解除する場合、onStop()は常にonStart()の後に呼び出されるため、バインドを解除するかどうかを決定するためにmBoundを用意する必要はありません。

したがって、ここで提供するコードでは、問題があるようには見えません。ただし、例外が発生している場合は、明らかに例外があるため、アプリの他の場所にある可能性があります。問題を絞り込むために、bindService()を呼び出すときにこのフラグを使用して、障害が発生したときにログに追加情報を取得できます。http: //developer.android.com/reference/android/content/Context.html# BIND_DEBUG_UNBIND

于 2011-07-11T03:06:28.437 に答える
0

いくつかのポイント:

  1. サービスをバインドされたアクティビティより長く存続させたい場合は、onStartCommandでSTART_STICKYを返します。
  2. unbindService()onStopは問題ありません。これは、複数のアプリで呼び出す場所であり、その特定のエラーは見たことがありません。ServiceConnectionに他の問題があると思います。mConnectionオブジェクトのコードを表示すると、おそらくそれの何が問題になっているのかを理解できます。
于 2011-07-11T03:05:56.603 に答える
0

私にもこの奇妙なエラーがありました。次に、ActivityのonStart()ではなくonResume()でサービスへのバインドを実行しようとしましたが、これ以上の例外はありません。なぜこれが機能するのか、私はまだ少し無知です。誰かが説明できれば、私は1人の幸せなコーダーになります。:)

于 2012-03-14T08:03:23.390 に答える