EventBus
とActivity
の間の通信にService
を使用しています。今日、私は問題を抱えていて、その理由がわかりません。
Activity
、Fragment
、およびService
があります。それらはすべて正常に動作しています。
Activity
とFragment
で、私はそれらをregistered
から配信されたReceive
events
にService
します。
Activity
とFragment
では、onDestroy()
が呼び出されたときにそれらを_un-register
_します。
通常、Services
がevents
を配信すると、Fragment
とActivity
はそれらのevents
を受け取り、正常に機能します。
ただし、App
がbackground
で押されると([ホーム]または[電源]ボタンを押す)、Fragment
のみがService
から配信されたイベントを受信し、Activity
はそれらを受信しません。
Activity
とFragment
の両方のonPause()
では何もしませんでした。
質問:
それについて何か説明はありますか?また、アプリがバックグラウンドでプッシュされたときにActivity
が行ったように、Fragment
がイベントを受信するようにするにはどうすればよいですか?
EventBusバージョン3.0.0では、スティッキー投稿を使用できます。
このようにして、「onStop()」でEventBusの登録を解除して、メモリリークを防ぎ、アプリがフォアグラウンドになったときにイベントを受信することができます。
この方法でイベントを投稿します。
EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));
次のように、スティッキーフラグを使用してイベントをサブスクライブします。
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {
textField.setText(event.message);
}
EventBusドキュメント: http://greenrobot.org/eventbus/documentation/configuration/sticky-events/
ユーザーが戻る/ホームボタンを押すと、Activity
はいつでも破棄される可能性があるため、EventBusを使用してデータを受信することはできません。 Activity
がバックグラウンドにあるときにデータを受信しようとすると、メモリリークが発生し、アプリがクラッシュする可能性があります。
ユーザーがActivity
を再開したときに、activity
のデータを取得する方法は他にもあります。
ユーザーsharedpreferences
またはローカルデータベースのいずれかを使用して、service
に渡された結果を保存できます。また、ユーザーがアクティビティに戻ったら、sharedpreferences
またはデータベースから読み取ります。
このようにして、メモリリークやデータ損失の問題は発生しません。
編集1:
アクティビティがフォアグラウンドにない場合、アクティビティはこれらのイベントを必要としないため、onPause
またはonStop
のいずれかでリスナーの登録を解除することを常にお勧めします。また、onDestroy()
が呼び出されることが保証されていないため、アクティビティが開いていなくてもブロードキャストを受信し続けることができます。
Activityクラスは、非表示時(バックグラウンドモード)のonStop()とonRestart()の2つのライフサイクルメソッドを提供します。これにより、アクティビティの停止と再開の処理方法を具体的に処理できます。部分的なUI障害を識別する一時停止状態とは異なり、停止状態はUIが表示されなくなり、ユーザーのフォーカスが別のアクティビティ(または完全に別のアプリ)にあることを保証します。
このサイクルを理解するために、アプリがフォアグラウンドモードを終了したときのフローを示すこの画像を見てください。
あなたの場合、あなたはこのような問題を扱うことができます。
ユーザーがアプリをコールバックするときは、onRestart()メソッドを使用してデータを復元する必要があります。
これを実装する方法は次のとおりです。
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from Android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
Android開発者サイト から次のドキュメントをお読みください
適切に支援するには、さらに多くのコードまたは例が必要です。ただし、次のことを試してください。
この動作を引き起こす原因を推測するのは難しいので、コードを提供することを検討してください。
しかし、明らかなことは、いくつかの設計上の欠陥があるということです。
ユーザーがアプリから戻ったときに、アクティビティやフラグメントなどのUIコンポーネントのイベントバスまたはリスナーから登録を解除する必要があります。登録を解除しないと、アクティビティとそれが保持するすべてのリソースがリークする可能性があります。
バックグラウンドサービスで受信または計算したデータはすべてファイルまたはデータベースに保存する必要があります。ユーザーがアプリを開いたり再度開いたりするときは、そのデータを確認して操作する必要があります。