您的位置:首页 > 其它

EventBus--事件总线

2016-05-13 12:58 323 查看
什么是EventBus

EventBus是Android下高效的发布/订阅事件总线机制。作用是可以代替传统的Intent,Handler,Broadcast或接口函数在Fragment,Activity,Service,线程之间传递数据,执行方法。特点是代码简洁,是一种发布订阅设计模式(Publish/Subsribe),或称作观察者设计模式。

下载EventBus

1.
下载EventBus库:
库地址:https://github.com/greenrobot/EventBus/releases
源码地址:https://github.com/greenrobot/EventBus
2.
将下载好的EventBus-2.4.0.jar放入libs即可

如何使用EventBus

1. 定义事件, 定义一个类,继承默认的Object即可,用于区分事件和传输数据。 本例为MsgEvent1和MsgEvent2
2. 添加订阅者:EventBus.getDefault().register(this);
将所在类作为订阅者,框架会通过反射机制获取所有方法及其参数。
 
  订阅者所在类可以定义以下一个或多个方法用以接收事件:

 
   public void onEvent(MsgEvent1
msg)

 
      public void onEventMainThread(MsgEvent1
msg)

 
      public void onEventBackgroundThread(MsgEvent1
msg)

 
      public void onEventAsync(MsgEvent1
msg)

3. 发布者发布事件:EventBus.getDefault().post(new MsgEvent1("主线程发的消息1"));
 
  一旦执行了此方法, 所有订阅者都会执行第二步定义的方法。
4.
取消订阅:EventBus.getDefault().unregister(this);
当订阅者不再被使用,或者被关闭时,最好进行取消订阅,不再接受事件消息。
5.
注意事项:发布者post方法参数是Object类型,也就是可以发布任何事件。订阅者接受消息时,只要定义的是第二步四个方法任意一个,并且参数和发布者发布的一致,即可被执行。发布者也可以通过第二步接收消息,订阅者也可以作为发布者发消息给自己。

代码实现 (本例是两个Fragment交互, 也可以是Service,Activity,Fragment以及任意类之间交互)

点击左边面板的条目, 可以发送事件,右面板(另一个Fragment)接收到事件,显示界面,打印日志。

代码下载 http://yunpan.cn/cctFTVuWtyIgK  访问密码
66ed

界面如下



1.主界面搭建:
java

public class MainActivity extends FragmentActivity {

        @Override

        protected void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.activity_main);

        }

}

复制代码
xml

<LinearLayout 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"

    tools:context="com.itheima.eventbusdemo.MainActivity" >

    <fragment

        android:id="@+id/left_fragment"

        android:name="com.itheima.eventbusdemo.LeftFragment"

        android:layout_width="0dip"

        android:layout_height="match_parent"

        android:layout_weight="1" />

    <fragment

        android:id="@+id/right_fragment"

        android:name="com.itheima.eventbusdemo.RightFragment"

        android:layout_width="0dip"

        android:layout_height="match_parent"

        android:layout_weight="3" />

</LinearLayout>

复制代码

2. 定一个事件类MsgEvent1 (MsgEvent2与此一致):

public class MsgEvent1 {

        private String msg;

        

        public MsgEvent1(String msg) {

                super();

                this.msg = msg;

        }

        public String getMsg() {

                return msg;

        }

}

复制代码

3. 将右面板作为订阅者, 执行方法并接收数据:

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);

        }

}

复制代码

4. 在左面板发布消息。(任意类都可以发布消息)

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<String>(getActivity(), android.R.layout.simple_list_item_1, strs));

        }

        

        @Override

        public void onListItemClick(ListView l, View v, int position, long id) {

                switch (position) {

                case 0:

                        // 主线程

                        System.out.println(

                                "----------------------主线程发的消息1" 

                                + " threadName: "+ Thread.currentThread().getName() 

                                + " threadId: " + Thread.currentThread().getId());

                        EventBus.getDefault().post(new MsgEvent1("主线程发的消息1"));

                        break;

                case 1:

                        // 子线程

                        new Thread(){

                                public void run() {

                                        System.out.println(

                                                "----------------------子线程发的消息1" 

                                                + " threadName: "+ Thread.currentThread().getName() 

                                                + " threadId: " + Thread.currentThread().getId());

                                        EventBus.getDefault().post(new MsgEvent1("子线程发的消息1"));

                                };

                        }.start();

                        

                        break;

                case 2:

                        // 主线程

                        System.out.println(

                                        "----------------------主线程发的消息2" 

                                        + " threadName: "+ Thread.currentThread().getName() 

                                        + " threadId: " + Thread.currentThread().getId());

                        EventBus.getDefault().post(new MsgEvent2("主线程发的消息2"));

                        break;

                }

        }

        

}

复制代码

分别点击左边条目,
Log输出分析


 

源码网盘地址: http://yunpan.cn/cctFTVuWtyIgK  访问密码 66ed

EventBus框架原理流程图


1. Publisher是发布者, 通过post()方法将消息事件Event发布到事件总线
2. EventBus是事件总线, 遍历所有已经注册事件的订阅者们,找到里边的onEvent等4个方法,分发Event
3. Subscriber是订阅者, 收到事件总线发下来的消息。即onEvent方法被执行。注意参数类型必须和发布者发布的参数一致

转载自:http://bbs.itcast.cn/thread-83609-1-1.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  第三方框架