Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次


Posted in Java/Android onApril 24, 2022

场景

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

Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次

由于是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就行。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。


Tags in this post...

Java/Android 相关文章推荐
总结一些Java常用的加密算法
Jun 11 Java/Android
SpringBoot2 参数管理实践之入参出参与校验的方式
Jun 16 Java/Android
dubbo服务整合zipkin详解
Jul 26 Java/Android
SpringBoot整合Mybatis Generator自动生成代码
Aug 23 Java/Android
Springboot如何同时装配两个相同类型数据库
Nov 17 Java/Android
springboot 自定义配置 解决Boolean属性不生效
Mar 18 Java/Android
Spring Boot配合PageHelper优化大表查询数据分页
Apr 20 Java/Android
Android开发实现极为简单的QQ登录页面
Apr 24 Java/Android
Android存储中最基本的文件存储方式
Apr 30 Java/Android
Java异常体系非正常停止和分类
Jun 14 Java/Android
详解Spring Security如何在权限中使用通配符
Jun 28 Java/Android
Spring Boot 使用 Spring-Retry 进行重试框架
Apr 24 #Java/Android
Android在Sqlite3中的应用及多线程使用数据库的建议
Apr 24 #Java/Android
Android开发 使用文件储存的方式保存QQ密码
Apr 24 #Java/Android
IDEA 2022 Translation 未知错误 翻译文档失败
Android开发实现极为简单的QQ登录页面
Flutter Navigator 实现路由传递参数
Apr 22 #Java/Android
SpringBoot 集成短信和邮件 以阿里云短信服务为例
You might like
全国FM电台频率大全 - 27 陕西省
2020/03/11 无线电
Smarty+QUICKFORM小小演示
2007/02/25 PHP
探讨:web上存漏洞及原理分析、防范方法
2013/06/29 PHP
php下拉选项的批量操作的实现代码
2013/10/14 PHP
java模拟PHP的pack和unpack类
2016/04/13 PHP
php执行多个存储过程的方法【基于thinkPHP】
2016/11/08 PHP
PHP随机获取未被微信屏蔽的域名(微信域名检测)
2017/03/19 PHP
PHP实现通过文本文件统计页面访问量功能示例
2019/02/13 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
不用写JS也能使用EXTJS视频演示
2008/12/29 Javascript
原生js实现给指定元素的后面追加内容
2013/04/10 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
jQuery实现的动态伸缩导航菜单实例
2015/05/07 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
JS实现搜索框文字可删除功能
2016/12/28 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
vue 数组和对象不能直接赋值情况和解决方法(推荐)
2017/10/25 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
2017/12/27 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
Python开发虚拟环境使用virtualenvwrapper的搭建步骤教程图解
2018/09/19 Python
详解python读取和输出到txt
2019/03/29 Python
基于python实现FTP文件上传与下载操作(ftp&sftp协议)
2020/04/01 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
2020/05/26 Python
python:删除离群值操作(每一行为一类数据)
2020/06/08 Python
Ellos丹麦:时尚和服装在线
2016/09/19 全球购物
what is the difference between ext2 and ext3
2015/08/25 面试题
食品科学与工程专业毕业生求职信范文
2014/07/21 职场文书
公司证明怎么写
2014/09/22 职场文书
债务追讨授权委托书范本
2014/10/16 职场文书
2014年骨干教师工作总结
2014/12/19 职场文书
2015年教师党员个人总结
2015/11/24 职场文书
十个Python自动化常用操作,即拿即用
2021/05/10 Python
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers