• Android 使用EventBus进行Fragment和Activity通信


    本文介绍EventBus的基本使用,以及用于Fragment和Activity之间通信。 
    github地址: https://github.com/greenrobot/EventBus 版本是 EventBus-2.4.0 release 
    EventBus是基于订阅和发布的一种通信机制,使用流程如下:

    • 实例化EventBus对象
    • 注册订阅者
    • 发布消息
    • 接受消息

    对应代码

    EventBus eventBus = new EventBus();
    eventBus.register(subscriber object);//注册订阅者
    订阅者对象中必须有 onEvent public 方法
    public void onEvent(Object event){
       //接收消息
    }
    eventBus.post(event);//发送消息

    应用到Activity和Fragment中

    因为订阅者必须有onEvent方法,因此我们创建一个基类让onEvent方法作为抽象方法

    public abstract class BaseFragment extends Fragment {
    
        public BaseFragment() {
        }
    
        public abstract void onEvent(MyEvent eventData);
    
    }

    MainActivity

    public class MainActivity extends FragmentActivity  {
    
        public Button btn;
        public EventBus eventBus;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn = (Button) findViewById(R.id.btn);
            eventBus = new EventBus();
    
            FragmentManager fm = getSupportFragmentManager();
            MyFragment myFragment = new MyFragment();
            fm.beginTransaction().replace(R.id.container, myFragment).commit();
    
            eventBus.register(myFragment);//注册订阅者 MyFragment
    
            btn.setOnClickListener(new OnClickListener() {
                public void onClick(View arg0) {
                    List<String> list = new ArrayList<String>();
                    list.add("test string");
                    MyEvent myEvent = new MyEvent();
                    myEvent.eventType = 1;
                    myEvent.data = list;
                    eventBus.post(myEvent);//发布消息
    
                    myEvent = new MyEvent();
                    myEvent.eventType = 2;
                    myEvent.data = new MyCallBack();//接口回调作为引用
                    eventBus.post(myEvent);//发布消息
                }
            });
    
        }
    
        //此时MainActivity作为订阅者
        public void onEvent(MyEvent event) {
            Log.d("", "onEvent >> callback main>>>" + event.data);
        }
    
        //回调接口也可以做为事件数据
        class MyCallBack implements DataCallBack {
    
            @Override
            public void onCallback(MyEvent eventData) {
                Log.d("", "eventData >>>> " + eventData);
            }
    
        }
    }

    封装的消息MyEvent

    public class MyEvent {
        public MyEvent() {
        }
        public int eventType;//可能类型有很多种,数据也不一样
        public Object data;//数据对象
    
    }

    MyFragment

    public class MyFragment extends BaseFragment {
    
        private DataCallBack actCallback;
        private EventBus eventBus;
    
        public MyFragment() {
            setHasOptionsMenu(true);
            eventBus = new EventBus();
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_main, null);
        }
    
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            view.findViewById(R.id.call).setOnClickListener(new OnClickListener() {
                public void onClick(View view) {
                    if (actCallback != null) { //得到接口后 回调一下
                        MyEvent event = new MyEvent();
                        event.data = "this is fragment:" + MyFragment.this;
                        actCallback.onCallback(event);//调用回调
                    }
                }
            });
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if (getActivity() != null) {
                eventBus.register(getActivity());//事件订阅者注册,订阅者为MainActivity
            }
        }
    
        @Override
        public void onEvent(MyEvent event) { 
            int type = event.eventType;
            if (type == 1) {
                Log.d("", "onEvent type 1:" + event.data);
            }
            else if (type == 2) {
                Log.d("", "onEvent type 2:" + (event.data instanceof DataCallBack));
                if (event.data instanceof DataCallBack) {
                    actCallback = ((DataCallBack) event.data);//得到回调
    
                    //发消息给MainActivity
                    MyEvent event2 = new MyEvent();
                    event2.data = "call main activity method";
                    eventBus.post(event2);//发布消息
                }
            }
        }
    }

    一般让Fragment调用Activity的方法有一下几种

    • 创建Fragment的时候把MainActivity引用传给Fragment,其实通过getActivity()也能获取到实例
    • 创建Fragment的时候传入一个Handler实例,在Fragment中sendMessage也是可以的
    • 创建Fragment的时候传入一个实例化接口,作为回调

    我觉得用接口的方式更加好,耦合性算是比较低的一种。当Fragment pop后 getActivity()获取的引用为NULL,传入Handler实例是可以的,但有些时候你可能用不上Handler这个东西。

    EventBus使用还是比较简单的,降低了代码耦合性,只需要在onEvent中处理数据即可。

  • 相关阅读:
    Kafka 配置
    Zookeeper的Watcher机制
    Ubuntu18.04下希捷移动硬盘Seagate Backup Plus读写慢
    Spring Boot 使用Jar打包发布, 并使用 Embedded Jetty/Tomcat 容器
    再谈C#委托与事件
    C#委托和事件例析
    PHP:session无法使用
    C++:实现类似MFC的IsKindOf功能
    C++:复制构造函数
    C++:运算符重载
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/8334563.html
Copyright © 2020-2023  润新知