EventBus是一种在Android中高效的发布/订阅的事件总线机制,主要作用是可以替代传统的Handler, intent, BroadCast在Activity, Fragment,sevice,线程之间传递数据 ,而且代码实现得更优雅,实现了发布者(Publisher)和接受者(Subcribler)的完美解耦。
/** * 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()方法取出数据,就是这么简单哦!
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组成。
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这里的leftFragment通过EventBus.getDefault().post()被定义为EventBus的发布者,post()中装载参数类型,这里很关键,到后面就知道了,跟着我走哈,别分心!(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; } } }
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的界面也随之更新。
/** * 与发布者在同一个线程 * @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); }
/** * 执行在主线程。 * 非常实用,可以在这里将子线程加载到的数据直接设置到界面中。 * @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); }我想这四个函数应该没问题吧!