Neglected Sanity
Neglected Sanity

Reputation: 1934

LocalBroadcastManager not receiving messages correctly

I have a, what I thought was a, simple task. I have a list of achievements in a recyclerView in my MainActivity. Clicking on one of the achievements launches the AchievementDetailActivity. You do an action in the AchievementDetailActivity and it completes the achievement. When that happens, I need the thumbnail on the MainActivity to be the achievement icon and not the locked icon. What I thought was I could just use the LocalBroadcastManager to send and receive messages from one activity to another, but that isn't working. From everything I have read you are supposed to unregister the listener in your activity onPause and onStop lifecycle methods, however, if you unregister the listener in the onPause of MainActivity, it gets unregistered when the AchievementDetailActivity starts and nothing gets delivered to the MainActivity. I don't understand how you can use LocalBroadCastManager with receivers to send information between activities when they get unregistered as soon as you start a new activity. The following example shows it unregisters as soon as the second activity is started, so the first activity will never get the broadcast...

public class MainActivity extends AppCompatActivity {

  public static final String ACTION = "update";

  private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("MAIN ACTIVITY", "RECEIVED EVENT");
    }
  }
  public void onStart() {
    super.onStart();
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver), new IntentFilter(ACTION));
  }

  public void onPause() {
    Log.d("MAIN ACTIVITY", "REMOVING LISTENER");
    LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
  }
  //.. The rest of MainActivity
}

public class SecondActivity extends AppCompatActivity {

  @Override
  public void onStart() {
    super.onStart();
    //initialize view and such
    button.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
        Intent intent = new Intent(MainActivity.ACTION);
        intent.putExtra("Something", "somewhere");
        manager.sendBroadcast(intent);
      }
    )};
  }

If you run the above, obviously with the buttons and such, you will get a message that shows it unregisters the listener as soon as SecondActivity starts and the MainActivity will never get the message it is supposed to get when you click a button on the second activity.

Is there a way to send information from activity to activity, or because of the lifecycle events is that not possible? Everything I read said LocalBroadcastManager was the right way to do it, but it gets unregistered so, how can it? Please help, this is driving me nuts. Thank you.

Upvotes: 0

Views: 449

Answers (2)

Sagar
Sagar

Reputation: 24907

Its not a great idea to use LocalBroadcastReceiver for this purpose. Use startActivityForResult instead. Follow this Official doc for implementation details.

The reason its not wokring is:

You are registering the receiver in onStart and unregistering it in onPause(). When your second activity is shown, onPause () will be called as a result the BroadcastReceiver is unregistered.

Its not a great idea to keep it registered since it would lead to memory leaks.

Upvotes: 0

Amrit kumar
Amrit kumar

Reputation: 524

If you want to use your LocalBroadcastManager to fetch results, do not unregister in onPause, in which case must to unregister in onDestroy().

If you startAvtivity only to fetch some results, it is a good way to startActivityForResult.

Upvotes: 0

Related Questions