LocalBroadcastManager не получает сообщения правильно

У меня есть, как мне казалось, простая задача. У меня есть список достижений в recyclerView в моем MainActivity. Щелчок по одному из достижений запускает AchievementDetailActivity. Вы выполняете действие в AchievementDetailActivity, и оно завершает достижение. Когда это происходит, мне нужно, чтобы миниатюра на MainActivity была значком достижения, а не заблокированным значком. Я думал, что могу просто использовать LocalBroadcastManager для отправки и получения сообщений от одного действия к другому, но это не работает. Из всего, что я прочитал, предполагается, что вы должны отменить регистрацию слушателя в методах жизненного цикла onPause и onStop, однако, если вы отмените регистрацию слушателя в onPause в MainActivity, он будет отменен при запуске AchievementDetailActivity, и ничего не будет доставлено в MainActivity. Я не понимаю, как вы можете использовать LocalBroadCastManager с приемниками для отправки информации между действиями, когда они отменяются, как только вы начинаете новое действие. В следующем примере показано, что регистрация отменяется, как только запускается второе действие, поэтому первое действие никогда не получит широковещательную рассылку...

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

Если вы запустите приведенное выше, очевидно, с помощью кнопок и т. д., вы получите сообщение, которое показывает, что он отменяет регистрацию слушателя, как только запускается SecondActivity, и MainActivity никогда не получит сообщение, которое он должен получить, когда вы нажимаете кнопку на втором деятельность.

Есть ли способ отправлять информацию от действия к действию, или из-за событий жизненного цикла это невозможно? Все, что я читал, говорило о том, что LocalBroadcastManager был правильным способом сделать это, но он отменяет регистрацию, так как же это возможно? Пожалуйста, помогите, это сводит меня с ума. Спасибо.


person Neglected Sanity    schedule 13.06.2018    source источник


Ответы (2)


Если вы хотите использовать LocalBroadcastManager для получения результатов, не делайте unregister в onPause, в этом случае необходимо использовать unregister в onDestroy().

Если вы startAvtivity только для получения каких-то результатов, это хороший способ startActivityForResult.

person Amrit kumar    schedule 14.06.2018
comment
Единственная проблема в том, что я специально не ищу результат от деятельности. Пользователь может либо перейти в подробное представление и просмотреть его, а затем вернуться к основному действию с помощью кнопки «Назад» на панели действий, либо выполнить задание, а затем вернуться с помощью кнопки «Назад» на панели действий. Поэтому я не думал, что начальная активность для результата применима, поскольку это был только вариант выполнения задачи. - person Neglected Sanity; 14.06.2018
comment
Вы можете оставить LocalBroadcastManager зарегистрированным до тех пор, пока не будет вызван onDestroy(). - person Amrit kumar; 15.06.2018

Не лучшая идея использовать LocalBroadcastReceiver для этой цели. Вместо этого используйте startActivityForResult. Подробности реализации см. в этом официальном документе.

Причина, по которой он не работает:

Вы регистрируете приемник в onStart и отменяете его регистрацию в onPause(). Когда будет показано ваше второе действие, будет вызван onPause (), поскольку BroadcastReceiver не зарегистрирован.

Не лучшая идея держать его зарегистрированным, так как это приведет к утечке памяти.

person Sagar    schedule 14.06.2018