Friday, March 25, 2016

EventBus : Activity does not receive event when app is in the background

Leave a Comment

I'm using EventBus to communicate between Activity and Service. Today I got a problem and don't know why.

  1. I have Activity, Fragment and Service. All of them are working fine.

  2. In Activity and Fragment I registered them to Receive events which delivered from Service

  3. In Activity and Fragment, I un-register them when onDestroy() was called.

  4. In normal cases, when Services delivers events, Fragment and Activity can receive those events and work well.

  5. But when App is pushed on the background (by presses Home or Power button), only Fragment receives events which delivered from Service, and Activity does not receive them.

  6. I did not do anything in onPause() both of Activity and Fragment.

Question:

Is there any explanation for that? And how can I make my Activity receives event like Fragment did when app is pushed on background?

4 Answers

Answers 1

When user presses back/home button, Activity can be destroyed anytime and thus you won't be able to receive the data using EventBus. If any how you are trying to receive the data when the Activity is in background, it may leak memory and the app will crash.

There can be other approaches to get the data in the Activity when user resumes the activity.

You can either user sharedpreferences or local database to save the results passed be the service. And when the user navigates back to the activity, read it from sharedpreferences or database.

This way there won't be any issue with memory leakage or data loss.

Edit 1:

It is always recommended to unregister listeners in either onPause or onStop because the activity does not need those events when it is not in the foreground. And since onDestroy() is not guaranteed to be called, thus you could continue receiving broadcasts when the Activity is no longer open.

Answers 2

The Activity class provides two lifecycle methods, onStop() and onRestart() when is not visible (background mode), which allow you to specifically handle how your activity handles being stopped and restarted. Unlike the paused state, which identifies a partial UI obstruction, the stopped state guarantees that the UI is no longer visible and the user's focus is in a separate activity (or an entirely separate app).

In order to understand this cycle, take a look a this image that shows the flow when your app goes out of foreground mode.

When the user leaves your activity

In your case you can handle the issue like this.

  • Provide to the user a mechanism to save persistent application data using either local database(Sqlite), sharedPreferences.
  • Handle your data persistency on onStop() method.
  • When user callback your app, then you will need to restore the data using onRestart() method.

    Here is the way to implement that.

    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(); } 

    }

Please read the following documentation from Android Developer site

Answers 3

It's hard to guess what you have done which causing this behavior, consider providing some code.

But what is obvious is that you have some design flaws.

You must unregister from any event bus or listener in your ui components like Activities or Fragments when user navigates back from the app, if you don't, there is a good chance to leak your activity and all of the resources which it holds.

You should store any data which you receive or calculate in your background service to a file or database, when user open or reopen your app you should check for that data and act on it.

Answers 4

Needs more codes or examples to properly help you. But try the following.

  1. Are your activities extended from a baseActivity? and if so remove the onDestroy eventbus unregister code and check.
  2. In developer options, check whether the don't keep activities option is unchecked.
  3. Pressing back will kill your app anyway unless u have overridden the back event.
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment