OTTO и фрагменты в других действиях

Я начал использовать OTTO by Square вчера, пока что у меня было хорошее начало.

Otto отлично работает из коробки, когда ваши фрагменты уже размещены в FragmentActivity, и вам просто нужно общаться между фрагментами, размещенными в этой FragmentActivity.

Когда вы уже размещены, ваш метод #onResume() вызывается, и фрагмент может зарегистрироваться на Eventbus:

@Override
public void onResume()
{
    super.onResume();
    BusProvider.getInstance().register(this);
}

Моя проблема:

Фрагмент, встроенный в дополнительную активность, которая должна получать событие через Eventbus, выглядит следующим образом:

public AnotherFragmentHostedInSomeActivity extends Fragment
{
         .....

    @Subscribe
    public void onSomethingHappend(final Event event)
    {

          final SomeObject deliveredObject = event.getSomeObject();

Но похоже, что все еще сложно, когда вы хотите вызвать другую активность, содержащую фрагмент, подобный этому коду:

public class SomeFragmentSendingDataToAnotherFragment extends Fragment
{
            ...
    private void sendData()
    {
            final Intent intent = new Intent(applicationContext, SomeActivity.class);
            applicationContext.startActivity(intent);                                 
            BusProvider.getInstance().post(new Event(someObject));

Как вы уже могли заметить, этот код хитрый. Запуск действия, а затем отправка данных во фрагмент, размещенный в этом действии, не может работать из-за жизненного цикла. Таким образом, создается действие и фрагменты. В какой-то момент вызывается метод onResume, чтобы фрагмент мог зарегистрироваться с помощью @Subscribe. Но все это происходит после того, как событие уже опубликовано через EventBus. Таким образом, фрагмент, представляющий интерес, никогда не вызывается EventBus.

Кто-нибудь знает, как это сделать по-умному?

Немного дополнительной информации: Вчера у меня была хорошая игра с OTTO. Проблема возникает только в моем проекте, когда мне нужно отправить данные в другое действие, что в моем случае происходит всегда, когда приложение работает на смартфоне, а не на планшете. Прежде чем я отправлю все данные через Intent и Parcelable. Отто уменьшит необходимость написания Parcleable Objects, поэтому я хотел бы пойти по этому пути.

Спасибо за ответы


person Kitesurfer    schedule 07.11.2012    source источник


Ответы (3)


К тому времени, когда начнется вторая активность, ваша исходная активность исчезнет. Как указывали другие, если вы хотите передавать данные из Activity в Activity, использование Intents, вероятно, является лучшим путем.

Если вам действительно нужна шина событий, вам нужен объект, который остается живым даже после того, как первая активность исчезнет. В Android это связано с контекстом приложения или, при использовании Dagger или Guice, @Singleton.

В этом синглтоне вы используете аннотацию Otto @Produce. Когда вторая активность подпишется на шину, она получит любые данные из этого метода @Produce.

person Eric Burke    schedule 08.11.2012
comment
Спасибо, Эрик, что прояснил это. У меня сложилось другое впечатление о том, что может сделать Автобус. Жизненный цикл просто не играет в эту игру. Поэтому мне все еще нужно знать, находится ли мой фрагмент в каком-то режиме планшета или телефона, чтобы запустить событие. - person Kitesurfer; 08.11.2012

Вы можете проверить ответ Джейка Уортона, опубликованный на Otto github issue. Вы можете использовать @Producer.

когда вы делаете HTTP-запросы и храните ответ где-то в кэше (скажем, в списке сотрудников). Большинство людей запускают запрос, и их деятельность напрямую действует, когда приходит ответ на какой-либо обратный вызов. Проблемы возникают здесь, когда этот обратный вызов происходит после onPause и до onResume, как это происходит, когда устройство вращается. Вместо этого вы можете опубликовать событие, когда HTTP-вызов возвращается на шину, чтобы любой, кто слушает, получил его, а также отправил его в кеш. Затем у вас может быть производитель, который обращается к кешу для получения результатов HTTP-вызова, если какие-либо новые подписчики заинтересованы в ответе. Таким образом, когда вы приостанавливаете свою активность (и отменяете регистрацию) и получаете ответный вызов, после возобновления (и повторной регистрации) вашему продюсеру будет вызвано, и активность будет уведомлена.

person Vijay Vankhede    schedule 04.12.2015

Вы пробовали использовать аннотацию @Produce? Как только ваш фрагмент во втором Activity зарегистрируется на шине, будет запущен любой метод @Subscribe, у которого есть соответствующий метод @Produce.

person SeanPONeil    schedule 07.11.2012
comment
Я попробовал это. Я также добавил подписчика DeadObject для получения всех недоставленных объектов. Я все еще вижу, что его вызывают. Я раскопал код ОТТО. Для меня проблема выглядит так, что активность увеличивается асинхронно до OTTO, в какой-то момент вызывается onResume, но в этом сценарии это слишком поздно. Я должен отложить почтовый звонок OTTO, чтобы это заработало, я думаю, что это тоже хитрость. IntentTool.showForecastActivity(getSherlockActivity().getApplicationContext()); BusProvider.getInstance().post (новое событие (объект)); - person Kitesurfer; 07.11.2012
comment
Мне кажется, что вы неправильно используете шину событий. Если вам нужно опубликовать событие во время запуска Activity, передайте данные через Intent. - person SeanPONeil; 07.11.2012
comment
Ну, я сделал это раньше. Если вы хотите, чтобы все было просто, я хочу использовать автобус, если это возможно. Поскольку у меня еще есть два метода, которые отвечают за обработку входящих данных. - person Kitesurfer; 07.11.2012
comment
Если вы хотите реагировать на событие сразу после создания фрагмента, используйте метод @Produces, а затем - person SeanPONeil; 07.11.2012