您的位置:首页 > 其它

EventBus深入浅析之基本使用

2016-07-18 10:35 309 查看

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到的,做了简单的修改,虽然很简单,但是很能说明问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息