3

I'm trying out Otto on Android and i'm trying to send back a message from my Fragment to the Activity. Here's the basics of my code:

My Bus provider:

public final class BusProvider {

 private static final Bus mInstance = new Bus();

 private BusProvider() {}

 public static Bus getBusProviderInstance() {
     return mInstance;
 }
}

My Activity has the following code:

public class MyActivity
        extends BaseActivity {

    // ....

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        BusProvider.getBusProviderInstance().register(this);
        // ....
    }

    @OnClick(R.id.profile_image)
    public void onImageClicked() {

        // ...

        MyFragment fragment = MyFragment.newInstance(choices);
        fragment.show(getFragmentManager(), "myChoices");
    }

    @Subscribe
    public void onButtonChoicePicked(MyFragment.ChoicePickedEvent event) {
        Toast.makeText(this, "reaching here", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onStop() {
        super.onStop();
        BusProvider.getBusProviderInstance().unregister(this);
    }

    // ...
}

and these are the important bits of code from my Fragment:

public class MyFragment
        extends BaseDialogFragment {

        // ...

        @Override
        public View onCreateView(LayoutInflater inflater,
                                 ViewGroup container,
                                 Bundle savedInstanceState) {

            LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.dialog_choices,
                                                                  container,
                                                                  false);
            setupDialogButtons(inflater, layout);
            return layout;
        }



    private void setupDialogButtons(LayoutInflater inflater, LinearLayout parentView) {
        ChoiceButtonViewHolder holder;

        holder = new ChoiceButtonViewHolder(inflater, parentView);
        holder.populateContent("First Choice", 1);

        parentView.addView(holder.mChoiceTextView);
    }


    class ChoiceButtonViewHolder {

        @InjectView(R.id.item_dialog_choice_desc) TextView mChoiceTextView;
        private int mPosition;

        ChoiceButtonViewHolder(LayoutInflater inflater, ViewGroup container) {
            TextView mChoiceTextView = (TextView) inflater.inflate(R.layout.item_dialog_choice, container, false);
            ButterKnife.inject(this, mChoiceTextView);
        }

        public void populateContent(String choiceDesc, int position) {
            mChoiceTextView.setText(choiceDesc);
            mPosition = position;
        }

        @OnClick(R.id.item_dialog_choice_desc)
        public void onChoiceClicked() {
            MyFragment.this.mDialog.dismiss();
            BusProvider.getBusProviderInstance().post(new ChoicePickedEvent(1));
        }
    }



    public static class ChoicePickedEvent {
        public int mPositionClicked;
        ChoicePickedEvent(int position) {
            mPositionClicked = position;
        }
    }
}

I don't get any errors. But when i click my button from the fragment, the event onButtonChoicePicked doesn't get called.

Am I doing something wrong? Am i misunderstanding how Otto works? Is it a weird combination of ButterKnife and Otto that makes it not work?

KG -
  • 7,130
  • 12
  • 56
  • 72
  • Have you used a break point or logged `onChoiceClicked()` from your Fragment to verify that it is being executed? – Bryan Dunlap Mar 09 '14 at 03:56
  • Hey Bryan, Yup when i debug. I reach onChoiceClicked, the getBusProviderInstance().post is also called. But nothing happens after that. The dialog is dismissed but the method on the Activity is not called. – KG - Mar 09 '14 at 03:59
  • Is `MyActivity` used directly, or is it a parent class that other activities extend from? – Bryan Dunlap Mar 09 '14 at 04:09
  • MyActivity is used directly. But it extends a BaseActivity (just like the Fragment). I've corrected the code to reflect this. – KG - Mar 09 '14 at 04:17
  • 1
    Looking at the code you've posted, I don't see anything that looks out of place. My other thought at this point is that `MyActivity` is somehow being unregistered from the `Bus` inadvertently, but that doesn't seem to be the case. Any code in your `BaseActivity` that messes with registration? – Bryan Dunlap Mar 09 '14 at 04:56
  • 1
    Thanks Bryan. on a whim, i tried with GreenRobot's EventBus and it worked. So i'm guessing it has nothing to do with the code. Your hint helped in that I noticed in some other parts of our code, we use Dagger to inject the Bus. I'm guessing there's some conflict/clash going on there. Will have to work it out some other time. Thanks for the help! I'm not inclined to figure out if Dagger is messing with my config now. But i'll report back if that's the case. – KG - Mar 09 '14 at 05:10
  • Glad to help, even if it wasn't much. That was the other thing that crossed my mind - different `Bus` instances - registering one instance in `MyActivity` and posting to different instance in `MyFragment`. But you are sourcing the `Bus` here using the `BusProvider` to produce a singleton, so that doesn't seem to be the case either. Good luck. – Bryan Dunlap Mar 09 '14 at 05:14
  • Any reason why you're not just using the Bus you're already provided via your Dagger module? That's probably the way to go. – powerj1984 Mar 09 '14 at 19:38
  • @powerj1984 yup that would be the logical next step for me to go but i wanted to understand better how the eventbus with otto worked, so was experimenting with it independently on a portion of the project. I still feel my code above should work, but i guess i'll have to figure out the conflicting bits. – KG - Mar 14 '14 at 18:35
  • Did you double check the the Subscribe import is "import com.squareup.otto.Subscribe;"? – jpardogo Aug 18 '14 at 16:46
  • thanks @jpardogo i've added an answer to the true problem. – KG - Aug 18 '14 at 19:33

2 Answers2

8

Make sure you are importing "com.squareup.otto.Subscribe" not "com.google.common.eventbus.Subscribe"

7

The example code works without any issues independently. The reason i was facing this problem initially (as was rightly pointed out by @powerj1984): There was a misconfiguration in my project, where the bus that was being injected (via Dagger) was different from the bus instance that was being subscribed to for updates :P.

Lesson learnt: make sure the bus you use, is the same instance in both cases.

KG -
  • 7,130
  • 12
  • 56
  • 72