千家信息网

Android怎么使用EventBus多次接收消息

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍"Android怎么使用EventBus多次接收消息"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Android怎么使用EventBus多次接
千家信息网最后更新 2025年01月16日Android怎么使用EventBus多次接收消息

这篇文章主要介绍"Android怎么使用EventBus多次接收消息"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Android怎么使用EventBus多次接收消息"文章能帮助大家解决问题。

场景

Fragment中嵌套Fragment,且被嵌套的Fragment是复用的,点击其中item后进入详情,返回后需要回传数据并刷新列表。

由于是Fragment之间的相互嵌套,不方便使用Intent返回数据,也不方便使用callback回调来返回数据,所以选择了使用EventBus发送消息,但是发现在列表中使用EventBus发送消息后,Fragment中接收消息的方法会执行多次。

发送消息:

EventBus.getDefault().post(new TestEvent());

接收消息:

@Subscribe(threadMode = ThreadMode.MAIN)    public void onTestEvent(TestEvent event) {       onSwipeRefresh();    }

也就是onTestEvent方法会被调用多次,数据也会多次刷新。

原因分析

因为Fragment是复用的,而EventBus订阅消息也在复用的Fragment中,导致该消息被多次订阅。以ItemFragment为例。

public class ItemFragment extends Fragment {    private static final String ARG_COLUMN_COUNT = "column-count";    private int mColumnCount = 1;    public ItemFragment() {    }    @SuppressWarnings("unused")    public static ItemFragment newInstance(int columnCount) {        ItemFragment fragment = new ItemFragment();        Bundle args = new Bundle();        args.putInt(ARG_COLUMN_COUNT, columnCount);        fragment.setArguments(args);        return fragment;    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);        }    }    @Override    public void onStart() {        super.onStart();        // 订阅消息        EventBus.getDefault().register(this);    }    @Override    public void onStop() {        super.onStop();        // 注销订阅        EventBus.getDefault().unregister(this);    }}

复用ItemFragment:

public class HomeFragment extends Fragment {    private int activeColor = Color.parseColor("#ffffff");    private int normalColor = Color.parseColor("#666666");    private final String[] tabs = new String[]{"第一页", "第二页", "第三页", "第四页", "第五页"};    public View onCreateView(@NonNull LayoutInflater inflater,                             ViewGroup container, Bundle savedInstanceState) {                            ...        vp2.setAdapter(new FragmentStateAdapter(getActivity().getSupportFragmentManager(), getLifecycle()) {            @NonNull            @Override            public Fragment createFragment(int position) {                return ItemFragment.newInstance(position + 10);            }            @Override            public int getItemCount() {                return tabs.length;            }        });        ...}

因为创建了5个ItemFragment对象,所以EventBus被订阅了5次,所以消息时也会被接收5次。

解决方案

1、提前在宿主Activity中进行EventBus消息订阅,但是该方法不适合多层级的Fragment嵌套,EventBus订阅不成功,也就接收不到消息。

2、在Fragment中添加标签,识别当前的Fragment。

@Override    public void onStart() {        super.onStart();        // 2 是需要接收消息的Fragment的索引        if(2 == position) {            EventBus.getDefault().register(this);        }    }    @Override    public void onStop() {        super.onStop();        if( 2 == position) {            EventBus.getDefault().unregister(this);        }    }

复用的Fragment中只有索引为2的Fragment才会订阅消息,所以发送消息的时候只有索引为2的Fragment才能接收到消息,也就解决了多次接收消息的问题。

3、消息中添加标记。

@Subscribe(threadMode = ThreadMode.MAIN)    public void onTestEvent(TestEvent event) {        if (event != null) {            // 2 是需要接收消息的Fragment的索引            if(event.getPosition() == 2){                onSwipeRefresh();            }        }    }

EventBus在post消息的时候,把需要哪一个页面刷新的position发送,接收消息时识别根据索引判断需要哪一个页面刷新。不一定要Fragment的position,只要能唯一识别Fragment就行。

关于"Android怎么使用EventBus多次接收消息"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

0