EventBus 事件总线 简介 案例

Posted 白乾涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EventBus 事件总线 简介 案例相关的知识,希望对你有一定的参考价值。


简介
EventBus是一款针对android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.
优点是开销小,代码更优雅,以及将发送者和接收者解耦。

包含4个成分:发布者,订阅者,事件,总线。
这四者的关系:订阅者订阅事件到总线,发送者发布事件;订阅者可以订阅多个事件,发送者可以发布任何事件,发布者同时也可以是订阅者。
技术分享
EventBus包含4个ThreadMode:PostThread,MainThread,BackgroundThread,Async
方法名为:onEventPostThread, onEventMainThread,onEventBackgroundThread,onEventAsync即可
  • onEventMainThread代表这个方法会在UI线程执行
  • onEventPostThread代表这个方法会在当前发布事件的线程执行
  • BackgroundThread这个方法,如果在非UI线程发布的事件,则直接执行,和发布在同一个线程中。如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用
  • Async 加入后台任务队列,使用线程池调用,注意没有BackgroundThread中的一个接一个

Activity
技术分享
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

<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:baselineAligned="false"
    android:divider="?android:attr/dividerHorizontal"
    android:orientation="horizontal"
    android:showDividers="middle" >
    <fragment
        android:id="@+id/item_list"
        android:name="com.angeldevil.eventbusdemo.ItemListFragment"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="1" />
    <fragment
        android:id="@+id/item_detail_container"
        android:name="com.angeldevil.eventbusdemo.ItemDetailFragment"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="2" />
</LinearLayout>

列表Fragment
/**
 * 1、在onCreate里面执行    EventBus.getDefault().register(this)意思是让EventBus【扫描当前类】,把所有以【onEvent】开头的方法使用Map记录下来<br>
 *      其中Key为方法的参数类型,Value值为包含该方法的对象,我们的【onEvent***()】方法就以键值对的形式存储到了EventBus中<br>
 * 2、当我们调用EventBus.getDefault().post(**)发布一个事件时,EventBus会根据post中的参数类型,去Map中查找对应的方法<br>
 * 3、于是在当前类中找到了我们的onEventMainThread(**)方法,最后通过反射去执行此方法。这就是为什么没有接口却能发生回调的原因。
 */
public class ItemListFragment extends ListFragment {
    private List<String> items = new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {//在onCreate里面进行了事件的订阅,onDestroy里面进行了事件的取消
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 开启线程加载列表
        new Thread() {
            public void run() {
                try {
                    for (int i = 0; i < 10; i++) {
                        items.add("id=" + i);
                    }
                    Thread.sleep(1000); // 模拟延时
                    // 在后台线程发布一个事件(一个FirstEvent的实例),当这个事件发布后,我们的onEventMainThread就被调用了(因为接收的是一个FirstEvent的实例)
                    EventBus.getDefault().post(new FirstEvent(items));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }
    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        super.onListItemClick(listView, view, position, id);
        //当点击ListView的Item时,在UI线程发布一个事件(SecondEvent类型)
        EventBus.getDefault().post(new SecondEvent("包青天" + position));
    }
    /**
     * 方法名以【onEvent】开头,代表要订阅一个事件;【MainThread】意思这个方法最终要在UI线程执行;当指定事件发布的时候,这个方法就会在UI线程自动执行
     */
    public void onEventMainThread(FirstEvent event) {
        ListAdapter adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, event.getItems());
        setListAdapter(adapter);
        //点击第一个item,只需要position即可
        onListItemClick(nullnull, 0, 0);
    }
}

详情Fragment
public class ItemDetailFragment extends Fragment {
    private TextView tv_info;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        tv_info = new TextView(getActivity());
        tv_info.setTextColor(Color.BLUE);
        tv_info.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
        return tv_info;
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    /** List点击时会发送此事件,接收到事件后更新详情 */
    public void onEventMainThread(SecondEvent item) {
        if (item != nulltv_info.setText("\n我收到了ItemListFragment发送的事件\n\n内容为:" + item.content);
    }
}

事件
/** 一个自定义的类,封装要发送的内容提供 */
public class FirstEvent {
    private List<String> items;
    public FirstEvent(List<String> items) {
        this.items = items;
    }
    public List<String> getItems() {
        return items;
    }
}

public class SecondEvent {
    public String content;
    public SecondEvent(String content) {
        this.content = content;
    }
}





附件列表

     

















    以上是关于EventBus 事件总线 简介 案例的主要内容,如果未能解决你的问题,请参考以下文章

    Shashlik.EventBus.NET 事件总线,分布式事务最终一致性简介

    Flutter EventBus事件总线的应用

    Flutter EventBus事件总线的应用

    EventBus 3.0使用与源码分析

    EventBus 3.0使用与源码分析

    EventBus 3.0使用与源码分析