Eventbus事件永远不会到达片段

时间:2017-02-03 07:51:46

标签: android android-fragments greenrobot-eventbus

我有一个片段A,点击一个按钮就会启动包含RecyclerView的片段B.在片段B中,单击项EventBus时,该值需要传递给片段A.但是,由于某种原因,该值永远不会到达片段A。

片段A

    public class OrderSummaryFragment extends BaseFragment implements OrderSummaryView {
    private static final String ARG_PARAM1 = "param1";
    public static final String ACTION_BACK = OrderSummaryFragment.class.getName() + ".back";
    public static final String ACTION_HIDE_ACTION_BAR = OrderSummaryFragment.class.getName() + ".hide_action_bar";
    public static final String ACTION_SHOW_ACTION_BAR = OrderSummaryFragment.class.getName() + ".show_action_bar";
    public static final String ACTION_CHANGE_ADDRESS = OrderSummaryFragment.class.getName() + ".select_address";

    FragmentOrderSummaryBinding mBinder;
    Shop mShop;
    OrderSummaryPresenter mPresenter;

    public OrderSummaryFragment() {

    }

    public static OrderSummaryFragment newInstance(Shop shop) {
        OrderSummaryFragment fragment = new OrderSummaryFragment();
        Bundle args = new Bundle();
        args.putParcelable(ARG_PARAM1, Parcels.wrap(shop));
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            Parcelable parcelable;
            parcelable = getArguments().getParcelable(ARG_PARAM1);
            mShop = Parcels.unwrap(parcelable);
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_order_summary, container, false);
        mPresenter = new OrderSummaryPresenterImpl(this);
        sendActionToActivity(ACTION_HIDE_ACTION_BAR);
        setUIListeners();
        EventBus.getDefault().register(this);
        return mBinder.getRoot();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mPresenter.loadBillingAddress(mShop);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        sendActionToActivity(ACTION_SHOW_ACTION_BAR);
        EventBus.getDefault().unregister(this);
        mPresenter.cleanup();
    }

    @Override
    protected void setTypeface() {
        mBinder.tvBackButton.setTypeface(FontManager.getInstance().getFontAwesome());
    }

    private void setUIListeners() {
        mBinder.tvBackButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendActionToActivity(ACTION_BACK);
            }
        });
        mBinder.btnChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendActionToActivity(ACTION_CHANGE_ADDRESS, mShop);
            }
        });
    }

    @Override
    public void renderBillingAddress(UserInfo userInfo) {
        mBinder.setUserInfo(userInfo);
        if (userInfo.getAddress2().equals("")) {
            mBinder.tvBillingAddress2.setVisibility(View.GONE);
        }
    }

    @Override
    public void renderPaymentTerms(List<PaymentInfo> paymentInfoList) {

    }

    @Override
    public void renderDeliveryMethod(List<DeliveryInfo> deliveryInfoList) {

    }

    @Override
    public void showProgress(boolean show) {

    }

    @Override
    public void showError(Error error) {

    }

    private void sendActionToActivity(String action) {
        if (mListener == null) {
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putString(Constants.ACTION_KEY, action);
        mListener.onFragmentInteraction(bundle);
    }

    private void sendActionToActivity(String action, Shop shop) {
        if (mListener == null) {
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putString(Constants.ACTION_KEY, action);
        bundle.putParcelable(Constants.DATA_KEY_1, Parcels.wrap(shop));
        mListener.onFragmentInteraction(bundle);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessage(ShippingAddressResult event) {
        UserInfo userInfo = event.getUserInfo();
        Log.d("Tag", "Test" + userInfo);
    }
}

片段B

    public class ShippingAddressFragment extends BaseFragment implements ShippingAddressView,
        ShippingAddressAdapter.OnItemInteractionListener {
    private static final String ARG_PARAM1 = "param1";
    public static final String ACTION_BACK = ShippingAddressFragment.class.getName() + ".back";
    public static final String ACTION_HIDE_ACTION_BAR = ShippingAddressFragment.class.getName() + ".hide_action_bar";
    public static final String ACTION_SHOW_ACTION_BAR = ShippingAddressFragment.class.getName() + ".show_action_bar";
    public static final String ACTION_NEW_ADDRESS = ShippingAddressFragment.class.getName() + ".new_address";

    FragmentShippingAddressBinding mBinder;
    Shop mShop;
    ShippingAddressAdapter mAdapter;
    ShippingAddressPresenterImpl mPresenter;
    List<UserInfo> mUserInfoList;

    public ShippingAddressFragment() {

    }

    public static ShippingAddressFragment newInstance(Shop shop) {
        ShippingAddressFragment fragment = new ShippingAddressFragment();
        Bundle args = new Bundle();
        args.putParcelable(ARG_PARAM1, Parcels.wrap(shop));
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            Parcelable parcelable;
            parcelable = getArguments().getParcelable(ARG_PARAM1);
            mShop = Parcels.unwrap(parcelable);
        }
        mUserInfoList = new ArrayList<>();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinder = DataBindingUtil.inflate(inflater, R.layout.fragment_shipping_address, container, false);
        setUIListener();
        mPresenter = new ShippingAddressPresenterImpl(this);
        sendActionToActivity(ACTION_HIDE_ACTION_BAR);
        mAdapter = new ShippingAddressAdapter(getContext(), mUserInfoList);
        mAdapter.addOnInteractionListener(this);
        LinearLayoutManager manager = new LinearLayoutManager(getContext());
        mBinder.rvShippingAddress.setLayoutManager(manager);
        mBinder.rvShippingAddress.addItemDecoration(new DividerItemDecoration(getActivity()));
        mBinder.rvShippingAddress.setAdapter(mAdapter);
        return mBinder.getRoot();
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mPresenter.loadShippingAddress(mShop);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mPresenter.cleanup();
        sendActionToActivity(ACTION_SHOW_ACTION_BAR);
        mAdapter.removeInteractionListener();
    }

    @Override
    protected void setTypeface() {
        mBinder.tvBackButton.setTypeface(FontManager.getInstance().getFontAwesome());
    }

    private void setUIListener() {
        mBinder.tvBackButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendActionToActivity(ACTION_BACK);
            }
        });
        mBinder.fabNewAddress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendActionToActivity(ACTION_NEW_ADDRESS, mShop);
            }
        });
    }

    @Override
    public void onClick(UserInfo userInfo) {
        selectedShippingAddress(userInfo);
        sendActionToActivity(ACTION_BACK);
    }

    @Override
    public void renderShippingAddress(List<UserInfo> userInfoList) {
        mUserInfoList.clear();
        mUserInfoList.addAll(userInfoList);
        mAdapter.notifyDataSetChanged();
    }

    private void sendActionToActivity(String action) {
        if (mListener == null) {
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putString(Constants.ACTION_KEY, action);
        mListener.onFragmentInteraction(bundle);
    }

    private void sendActionToActivity(String action, Shop shop) {
        if (mListener == null) {
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putString(Constants.ACTION_KEY, action);
        bundle.putParcelable(Constants.DATA_KEY_1, Parcels.wrap(shop));
        mListener.onFragmentInteraction(bundle);
    }

    private void sendActionToActivity(String action, Shop shop, AllCheckoutInfo allCheckoutInfo) {
        if (mListener == null) {
            return;
        }
        Bundle bundle = new Bundle();
        bundle.putString(Constants.ACTION_KEY, action);
        bundle.putParcelable(Constants.DATA_KEY_1, Parcels.wrap(shop));
        bundle.putParcelable(Constants.DATA_KEY_2, Parcels.wrap(allCheckoutInfo));
        mListener.onFragmentInteraction(bundle);
    }

    @Override
    public void showProgress(final boolean show) {

    }

    @Override
    public void showError(Error error) {

    }

    private void selectedShippingAddress(UserInfo userInfo) {
        ShippingAddressResult event;
        event = new ShippingAddressResult();
        event.setUserInfo(userInfo);
        EventBus.getDefault().post(event);
    }
}

2 个答案:

答案 0 :(得分:9)

由于您正在使用片段B替换片段A,因此在触发事件时,片段A未处于活动状态/已注册以捕获它。订阅者在被解雇时会定期查看订阅者,然后死亡。如果当时有该事件的任何订阅者,他们将收到该事件。这就是Sticky Events拯救的地方。粘性事件“坚持”。订阅者在其发布时刻之后订阅(粘贴)粘性事件仍将获得它。为此,请执行以下操作。

EventBus.getDefault().post(event);替换为EventBus.getDefault().postSticky(event);

并使您的ShippingAdressResult订阅成为粘性:

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onMessage(ShippingAddressResult event) {
    UserInfo userInfo = event.getUserInfo();
    Log.d("Tag", "Test" + userInfo);
    EventBus.getDefault().removeStickyEvent(stickyEvent); // don't forget to remove the sticky event if youre done with it
}

More Info

答案 1 :(得分:1)

我认为Sticky Event就是你所需要的。如果您没有任何订阅者消费活动,它将等到您订阅。当你要更换碎片时,这可能是你的情况。

EventBus.getDefault().postSticky(event);

如果您不再需要此活动,请不要忘记将其删除。

EventBus.getDefault().removeStickyEvent(stickyEvent);
祝你好运!