Eventbus 事件永远不会到达片段

Eventbus event never gets to the fragment

我有一个片段 A,单击按钮将启动包含 RecyclerView 的片段 B。在 Fragment B 中,点击一个项目 EventBus 会启动,该值需要传递给 Fragment A。但是,由于某种原因,该值永远不会到达 Fragment 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);
    }
}

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

EventBus.getDefault().postSticky(event);

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

EventBus.getDefault().removeStickyEvent(stickyEvent);

祝你好运!

由于您要用片段 B 替换片段 A,因此当事件被触发时,片段 A 不会 alive/registered 来捕捉它。常规事件在被解雇时会寻找订阅者,然后消失。如果当时有该事件的任何订阅者,他们将收到该事件。这就是 Sticky Events 派上用场的地方。粘性事件 "stick" 左右。在 post 时刻之后订阅(粘性)粘性事件的订阅者仍然会得到它。为此,请执行以下操作。

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