2

アクションを実行するインテント サービスを使用しており、アクションの結果を開始したアクティビティに戻す必要があります。

私は何十もの同様の投稿を検索しましたが、私が知る限り、私が見つけたすべての解決策には問題があります. 画面の回転をうまく処理しません。アクティビティがインテント サービスを開始し、サービスがアクションを実行するのに 10 秒かかり、その 10 秒間に画面が回転するとします。アクティビティが破棄され、新しいアクティビティが作成されます。

  1. Use Receiver : メモリ リークが発生します。これは、レシーバーが破棄する必要があるアクティビティにバインドされているため、アクティビティが破棄されないためです。
  2. Use Broadcast : リスナーを登録し、アクティビティが破棄される前にリスナーを登録解除する必要があります。リスナーが登録解除された後、新しいアクティビティのリスナーが登録される前にブロードキャスト メッセージが到着した場合、メッセージは受信されません。
  3. メッセージを使用する : 受信者と同じです。
  4. リスナーで共有設定/データベースを使用する: ブロードキャストと同じ。

私が思いついた解決策は、サービスに結果を設定ファイルに保存させ、設定ファイルの変更を定期的に (たとえば 200 ミリ秒ごとに) チェックするアクティビティです。したがって、画面が回転すると、アクティビティはチェックを停止し、再作成されると再び開始します。結果がその間に配信された場合でも、(再作成された) アクティビティに到達します。ただし、これはCPUを消費し、SDカードから不要な読み取りを実行するようです。

別の解決策は、サービスが結果を設定ファイル/データベースに保存し、それを保存した時刻にグローバル変数を設定することです。アクティビティには、設定ファイル/データベースへのリスナーがあります。リスナーを登録する前に、グローバル変数をチェックして、画面の回転中に結果が配置されたかどうか (グローバル変数 < currentTimeMillies()) を確認し、真の場合は結果を取得し、そうでない場合はリスナーを登録します。結果はチェックと登録の間に配置される可能性があるため、これは、サービスが結果を配置するために取得する必要があるロックをアクティビティが保持するブロック内で実行する必要があります。これも機能しますが、複雑すぎます。

画面の回転に耐えながら、よりシンプルでエレガントな方法はありますか?

4

1 に答える 1

1

この質問に対する私の答えを見てください:

サービスとアクティビティ (およびそのサブアクティビティ) の間で IPC を処理する方法は?

おそらくそれはあなたにアイデアを与えるでしょう。

編集(次の提案を追加):

別のアプローチは、アクティビティで作成したレシーバーを使用することです。画面の回転時に、OS は onRetainNonConfigurationInstance() を呼び出します。ここで Receiver インスタンスを返すことができ、新しいアクティビティに渡されます (getLastNonConfigurationInstance() を参照)。注: これらのメソッドは 4.0 で非推奨になり、Fragment と setRetainInstance() を使用して同様の動作を実現できます。

于 2012-05-22T16:52:04.050 に答える