打开APP
未登录
开通VIP,畅享免费电子书等14项超值服
开通VIP
首页
好书
留言交流
下载APP
联系客服
EventBus事件总线
月无影hvrpm993
>《webservice》
2016.11.16
关注
本帖最后由 唐杨 于 2015-7-23 19:22 编辑
什么是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方法被执行。注意参数类型必须和发布者发布的参数一致。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报
。
打开APP,阅读全文并永久保存
查看更多类似文章
猜你喜欢
类似文章
【热】
打开小程序,算一算2024你的财运
android——浅谈归纳Handler各种用法
【转】Handler: 主线程如何通知子线程
Android Handler机制
Android 判断当前线程是否是主线程的方法
android的Handler - 程序员之路 - 博客园
android中Invalidate和postInvalidate的区别
更多类似文章 >>
生活服务
热点新闻
留言交流
回顶部
联系我们
分享
收藏
点击这里,查看已保存的文章
导长图
关注
一键复制
下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!
联系客服
微信登录中...
请勿关闭此页面
先别划走!
送你5元优惠券,购买VIP限时立减!
5
元
优惠券
优惠券还有
10:00
过期
马上使用
×