EventBus深入浅析之基本使用
来源:互联网 发布:各种编程语言的区别 编辑:程序博客网 时间:2024/06/05 07:04
1.EventBus是什么?
EventBus是一个发布/订阅的事件总线;EventBus可以理解为包含:发布者-订阅者-事件-总线; 记忆:订阅者订阅事件到总线,发布者发布事件;订阅者可以订阅多个事件,发布者可以发布任何事件,发布者可以同时是订阅者。
2.EventBus基本使用。
提出需求:
1.两个fragment组成主界面,左边是目录,右边是详情;
2.目录是从网络上获取的;
3. 点击左边条目,右边动态获取条目对应的详情;
传统写法:
1.目录fragment在oncreate方法中开启线程,访问网络获取目录信息。
2.在目录fragment中提供接口,在详情fragment中注册本接口,在左边条目发生点击时回掉本接口,让详情信息发生改变。
代码:
public class ItemListFragment extends ListFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Register EventBus.getDefault().register(this); } @Override public void onDestroy() { super.onDestroy(); // Unregister EventBus.getDefault().unregister(this); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 开启线程加载列表 new Thread() { public void run() { try { Thread.sleep(2000); // 模拟延时 // 发布事件,在后台线程发的事件 EventBus.getDefault().post(new ItemListEvent(Item.ITEMS)); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } public void onEventMainThread(ItemListEvent event) { setListAdapter(new ArrayAdapter<Item>(getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, event.getItems())); } @Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); EventBus.getDefault().post(getListView().getItemAtPosition(position)); } }
onCreate里面进行了事件的订阅,
onDestroy里面进行了事件的取消;
onViewCreated中我们模拟了一个子线程去网络加载数据,获取成功后我们调用了EventBus.getDefault().post(new ItemListEvent(Item.ITEMS));发布了一个事件;
onListItemClick则是ListView的点击事件,我们调用了EventBus.getDefault().post(getListView().getItemAtPosition(position));去发布一个事件,
然后,在 new Thread()获取到数据以后,没有使用handler,界面竟然发生了变化,那么,问题来了,list是什么时候绑定的数据呢?
答案:
public void onEventMainThread(ItemListEvent event) { setListAdapter(new ArrayAdapter<Item>(getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, event.getItems())); }
这个方法绑定了数据,可是这个方法是怎么被调用的呢?
我们需要清楚的知道订阅事件和发布事件的规则:
如果方法名以onEvent开头,则代表要订阅一个事件,MainThread意思,这个方法最终要在UI线程执行;当事件发布的时候,这个方法就会被执行。
事件的发布:
EventBus.getDefault().post(new ItemListEvent(Item.ITEMS));
发布了一个事件,当这个事件发布,我们的onEventMainThread就执行了
现在我们完整的理一下:
在onCreate里面执行 EventBus.getDefault().register(this);意思是让EventBus扫描当前类,把所有onEvent开头的方法记录下来,如何记录呢?使用Map,Key为方法的参数类型,Value中包含我们的方法。
这样在onCreate执行完成以后,我们的onEventMainThread就已经以键值对的方式被存储到EventBus中了。
然后当子线程执行完毕,调用EventBus.getDefault().post(new ItemListEvent(Item.ITEMS))时,EventBus会根据post中实参的类型,去Map中查找对于的方法,于是找到了我们的onEventMainThread,最终调用反射去执行我们的方法。
现在应该明白了,整个运行的流程了;那么没有接口却能发生回调应该也能解释了。
现在我们在看看代码,当Item点击的时候EventBus.getDefault().post(getListView().getItemAtPosition(position));我们同样发布了一个事件,参数为Item;这个事件是为了让详细信息的Fragment去更新数据,不用说,按照上面的推测,详细信息的Fragment里面一个有个这样的方法: public void onEventMainThread(Item item) ;
public class ItemDetailFragment extends Fragment { private TextView tvDetail; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // register EventBus.getDefault().register(this); } @Override public void onDestroy() { super.onDestroy(); // Unregister EventBus.getDefault().unregister(this); } /** List点击时会发送些事件,接收到事件后更新详情 */ public void onEventMainThread(Item item) { if (item != null) tvDetail.setText(item.content); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false); tvDetail = (TextView) rootView.findViewById(R.id.item_detail); return rootView; } }
真的存在onEventMainThread(Item item)的方法。当然了,必须在onCreate里面首先书写EventBus.getDefault().register(this);让EventBus扫描再说。
那么这个Fragment的流程就是:onCreate时,EventBus扫描当前类,将onEventMainThread以键值对的形式进行存储,键为Item.class ,值为包含该方法的对象。
然后当ItemListFragment中Item被点击时,发布了一个事件:EventBus.getDefault().post(getListView().getItemAtPosition(position));实参的类型恰好是Item,于是触发我们的
onEventMainThread方法,并把Item实参传递进来,我们更新控件。
3.最后
可以利用EventBus尝试做以下操作:
当接收到某个广播,例如短信,在界面上显示。
开启一个Service,在服务器里面启动一个定时线程,不断更新ActivityUI。
等等…之后,你会发现EventBus的魅力!
声明一下:上面两个Fragment的例子是我在网上down到的,做了简单的修改,虽然很简单,但是很能说明问题。
- EventBus深入浅析之基本使用
- 深入理解EventBus - 基本使用
- Eventbus的基本使用
- Android EventBus 基本使用
- EventBus基本使用简介
- EventBus的基本使用
- eventbus基本使用
- EventBus的基本使用
- EventBus基本使用
- EventBus基本使用
- Android之EventBus源码浅析
- Android EventBus的基本使用
- Android:EventBus-3 基本使用
- EventBus使用之基础
- EventBus使用之基础
- EventBus使用之基础
- EventBus的使用与深入学习
- EventBus的使用与深入学习
- 汇编语言的数据段内的问号'?'表示多大的值?
- 8A - Train and Peter
- 完美集群监控组合ganglia和nagios
- HDU 1108
- gmaping建图环境
- EventBus深入浅析之基本使用
- C语言写文件问题,一个你想也想不到的问题。
- spring XML配置导入不了properties文件
- 关闭DevExpress
- dom4j实现读入写出xml
- 基于视频的车辆识别
- [笔记]常用SQL语句
- C#线程(一)
- Bzoj 3209 花神的数论题