1.EventBus是什么?

     EventBus是一种在Android中高效的发布/订阅的事件总线机制,主要作用是可以替代传统的Handler, intent, BroadCast在Activity, Fragment,sevice,线程之间传递数据 ,而且代码实现得更优雅,实现了发布者(Publisher)和接受者(Subcribler)的完美解耦。

2.EventBus的基本用法

1.下载EventBus库,链接地址:https://github.com/greenrobot/EventBus/releases 2.将下载好的EventBus-2.4.0.jar复制在自己工程的libs目录中 3.新建一个自定义类,用于区分事件和传递数据(我这里是MsgEvent1,MsgEvent2,MsgEvent3) 由于类代码重复,这里只贴出MsgEvent1
/** * Created by zhangxing on 2016/10/21. */public class MsgEvent1 {        private String msg;        public MsgEvent1(String msg) {            super();            this.msg = msg;        }        public String getMsg() {            return msg;        }    }
很简单吧,申明一个带参放的构造方法,用于接收数据,通过getMsg()方法取出数据,就是这么简单哦! 4.新建MainActivity,我在activity_main中申明两个fragment(leftFragment,rightFragment)
public class MainActivity extends FragmentActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}
activity_main.xml:
xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:divider="?android:attr/dividerHorizontal"    android:orientation="horizontal"    android:showDividers="middle"    android:baselineAligned="false"     >            android:id="@+id/left_fragment"        android:name="hongda.zhangxing.com.eventbardemo.fragment.LeftFragment"        android:layout_width="0dip"        android:layout_height="match_parent"        android:layout_weight="2" />            android:id="@+id/right_fragment"        android:name="hongda.zhangxing.com.eventbardemo.fragment.RightFragment"        android:layout_width="0dip"        android:layout_height="match_parent"        android:layout_weight="3" />
很清晰的明白,主界面由两个fragment组成。 5.leftFragment代码:(发布者)
public class LeftFragment extends ListFragment {    @Override    public void onViewCreated(View view, Bundle savedInstanceState) {        super.onViewCreated(view, savedInstanceState);        String[] strs = new String[]{"主线程消息1", "子线程消息1", "主线程消息2"};        setListAdapter(new ArrayAdapter(getActivity(), R.layout.item_list, strs));    }    @Override    public void onListItemClick(ListView l, View v, int position, long id) {        switch (position) {            case 0:                // 主线程                System.out.println("我是主线程发送的消息1,小牧");                EventBus.getDefault().post(new MsgEvent1("主线程发的消息1"));                break;            case 1:                // 子线程                new Thread(){                    public void run() {                        System.out.println("我是子线程发送的消息1,小星");                        EventBus.getDefault().post(new MsgEvent1("子线程发的消息1"));                    };                }.start();                break;            case 2:                // 主线程                System.out.println("我是主线程发送的消息2,小皮");                EventBus.getDefault().post(new MsgEvent2("主线程发的消息2"));                break;        }    }}
这里的leftFragment通过EventBus.getDefault().post()被定义为EventBus的发布者,post()中装载参数类型,这里很关键,到后面就知道了,跟着我走哈,别分心! 6.那么rightFragment在搞么事?
public class RightFragment extends Fragment {    private TextView tv;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 界面创建时,订阅事件, 接受消息       EventBus.getDefault().register(this);    }    @Override    public void onDestroy() {        super.onDestroy();        // 界面销毁时,取消订阅        EventBus.getDefault().unregister(this);    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // 布局只有一个TextView,不再贴代码        View view = inflater.inflate(R.layout.fragment_right, null);        tv = (TextView) view.findViewById(R.id.tv);        return view;    }    /**     * 与发布者在同一个线程     * @param msg 事件1     */    public void onEvent(MsgEvent1 msg){        String content = msg.getMsg()                + "\n ThreadName: " + Thread.currentThread().getName()                + "\n ThreadId: " + Thread.currentThread().getId();        System.out.println("onEvent(MsgEvent1 msg)收到" + content);    }    /**     * 执行在主线程。     * 非常实用,可以在这里将子线程加载到的数据直接设置到界面中。     * @param msg 事件1     */    public void onEventMainThread(MsgEvent1 msg){        String content = msg.getMsg()                + "\n ThreadName: " + Thread.currentThread().getName()                + "\n ThreadId: " + Thread.currentThread().getId();        System.out.println("onEventMainThread(MsgEvent1 msg)收到" + content);        tv.setText(content);    }    /**     * 执行在子线程,如果发布者是子线程则直接执行,如果发布者不是子线程,则创建一个再执行     * 此处可能会有线程阻塞问题。     * @param msg 事件1     */    public void onEventBackgroundThread(MsgEvent1 msg){        String content = msg.getMsg()                + "\n ThreadName: " + Thread.currentThread().getName()                + "\n ThreadId: " + Thread.currentThread().getId();        System.out.println("onEventBackgroundThread(MsgEvent1 msg)收到" + content);    }    /**     * 执行在在一个新的子线程     * 适用于多个线程任务处理, 内部有线程池管理。     * @param msg 事件1     */    public void onEventAsync(MsgEvent1 msg){        String content = msg.getMsg()                + "\n ThreadName: " + Thread.currentThread().getName()                + "\n ThreadId: " + Thread.currentThread().getId();        System.out.println("onEventAsync(MsgEvent1 msg)收到" + content);    }    /**     * 与发布者在同一个线程     * @param msg 事件2     */    public void onEvent(MsgEvent2 msg){        String content = msg.getMsg()                + "\n ThreadName: " + Thread.currentThread().getName()                + "\n ThreadId: " + Thread.currentThread().getId();        System.out.println("onEvent(MsgEvent2 msg)收到" + content);        tv.setText(content);    }}
嗦嘎,rightFragment通过onCreate()中的EventBus.getDefault().register(this)注册了EventBus,所以呢,他就被任命为了接受者,你注册了我,就要接受我的事件消息;有点像你既然娶了我,就要三千水,只取一瓢饮,对我负责!哈哈,我逗逼了一把,这里只是让各位更好的理解EventBus注册的真正用意。 好了,整个框架就算搭成功了,需求是点击左边的fragment的item,右边的fragment的界面也随之更新。 7.效果图:


文字不重要,看重点!

3.EventBus的进阶

有人也许耐不住性子了,锅锅,到底是怎么传递数据的啊,哈哈,小兄弟,消消气,馒头来了! 1.注册EventBus类中的函数解析 ①onEvent: 如果使用onEvent作为订阅函数,那么该事件在哪个线程发布出来的,onEvent就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
/** * 与发布者在同一个线程 * @param msg 事件2 */public void onEvent(MsgEvent2 msg){    String content = msg.getMsg()            + "\n ThreadName: " + Thread.currentThread().getName()            + "\n ThreadId: " + Thread.currentThread().getId();    System.out.println("onEvent(MsgEvent2 msg)收到" + content);    tv.setText(content);}

②onEventMainThread : 如果使用onEventMainThread作为订阅函数,那么不论事件是在哪个线程中发布出来的,onEventMainThread都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在Android中只能在UI线程中跟新UI,所以在onEvnetMainThread方法中是不能执行耗时操作的。
/** * 执行在主线程。 * 非常实用,可以在这里将子线程加载到的数据直接设置到界面中。 * @param msg 事件1 */public void onEventMainThread(MsgEvent1 msg){    String content = msg.getMsg()            + "\n ThreadName: " + Thread.currentThread().getName()            + "\n ThreadId: " + Thread.currentThread().getId();    System.out.println("onEventMainThread(MsgEvent1 msg)收到" + content);    tv.setText(content);}

③onEventBackground: 如果使用onEventBackgrond作为订阅函数,那么如果事件是在UI线程中发布出来的,那么onEventBackground就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么onEventBackground函数直接在该子线程中执行。
/** * 执行在子线程,如果发布者是子线程则直接执行,如果发布者不是子线程,则创建一个再执行 * 此处可能会有线程阻塞问题。 * @param msg 事件1 */public void onEventBackgroundThread(MsgEvent1 msg){    String content = msg.getMsg()            + "\n ThreadName: " + Thread.currentThread().getName()            + "\n ThreadId: " + Thread.currentThread().getId();    System.out.println("onEventBackgroundThread(MsgEvent1 msg)收到" + content);}

④onEventAsync: 使用这个函数作为订阅函数,那么无论事件在哪个线程发布,都会创建新的子线程在执行onEventAsync.
/** * 执行在在一个新的子线程 * 适用于多个线程任务处理, 内部有线程池管理。 * @param msg 事件1 */public void onEventAsync(MsgEvent1 msg){    String content = msg.getMsg()            + "\n ThreadName: " + Thread.currentThread().getName()            + "\n ThreadId: " + Thread.currentThread().getId();    System.out.println("onEventAsync(MsgEvent1 msg)收到" + content);}
我想这四个函数应该没问题吧! 2.到底具体怎样调用订阅函数,这是关键 调用原则:根据发布者调用post()方法时传入的参数类型,然后对应接收者的订阅函数的入参类型,对号入座,进行有目的性的调用。 这里我还是证实一下: 我将发布者的post()中的参数全部改成MsgEvent1的实例:

我将订阅函数onEvent()的入参传入MsgEvent1类型,目的只让它一个人接收发布者的信息:

我们来看看Logcat:见证奇迹的时刻来了!



是不是?哈哈,我猜的对吧!好了,今天的EventBus就告一段落,有什么问题私信我,我是张星,欢迎您的关注,后期更精彩!!




更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Android(安卓)处理横竖屏切换事件
  3. android listview 和button 共存的事件响应问题。
  4. android事件分发机制(上)
  5. Android(安卓)Looper和Handler
  6. Android中Touch事件流向
  7. Android(安卓)RecyclerView设置点击事件
  8. Android消息机制(三):Looper
  9. IntentService原理

随机推荐

  1. Android,对话框定时自动关闭的实现
  2. android apk版本更新
  3. Android入门第十一篇之TabHost,TabWidget
  4. Android:基于Eclipse编译调试系统级应用
  5. 吊打面试官:Android中高级面试题 -- 终局
  6. Android(安卓)模拟器安装及使用
  7. Android事件处理--读书笔记
  8. Android robotium自动化测试
  9. 10个经典的Android开源项目(附源码包)
  10. Android TV 智能电视/盒子 APP 开发焦点