1

APIレベル4以上からのターゲティングと構築。

現在、複数のアクティビティにわたってローカルサービスへのバインドを維持し、最後の接続がバインド解除されたときにサービスを停止しようとしている問題に対処しています。

簡単に言うと、私のサービスはHandlerThreadでシステムサービスを呼び出し、BroadcastReceiverにすばやく戻り、事前に決められた時間(少なくとも15秒)待った後、同じ呼び出しを再度実行します。

基本アクティビティで、onCreate()のサービスへの最初の結合を次のように作成するとします。

Intent service = new Intent(ActivityA.this, MyLocalService.class);
getApplicationContext().bindService(service, mConnection, BIND_AUTO_CREATE);

また、バインダーと接続を引き継ぐことで画面の回転全体でバインディングを維持しているため、アクティビティが終了するまでサービスからバインドを解除しないと仮定します。//onRetainNonConfigurationInstanceは、からバインドしたため、バインダーと接続を引き継ぎます。アプリのコンテキストなので、公正なゲームです。

public void onDestroy(){
   super.onDestroy();
   //using binder, remove callback to service from current activity
   if(isFinishing(){
      getApplicationContext().unbindService(mConnection);
   }
}

この設定は、サービスをリッスンしたい他のアクティビティに対してほとんど行います。

私の問題は、最終的に一部のアクティビティがすぐにバインド解除されないため、サービスが自動作成された場合、バインド/バインド解除パターンの動作に従ってサービスがハングアップすることです。最後のアクティビティでバインドを解除する前に、スレッドを停止するところまで行かなければなりませんでした。これにより、BGでシステムサービスが呼び出されなくなりました。バインドサービスとバインド解除サービスを管理するためのより良い方法はありますか、それとも現在の設定で最善を尽くしていますか?また、(バインダーを介した)私のサービスは弱く参照されているので、これによりメモリリークのリスクが軽減されますか?

4

1 に答える 1

1

どうやら、ローテーション間でバインディングを渡しておらず、内部状態フラグを使用してアクティビティがローテーションしているかどうかを判断していたため、登録解除されていなかったようです (onRetainNonConfigurationInstance() がと呼ばれる)。ほとんどの場合、onDestroy() で状態を適切に読み取っていませんでした。

onDestroy() で isFinishing() が true に解決され、onRetainNonConfigurationInstance() を介してバインディングが渡されたときにバインドを解除し、その結果、最後のバインド解除でサービスをシャットダウンできました。

于 2011-05-16T15:27:43.927 に答える