天天看點

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

最近大家面試說經常被問到eventbus,github上果斷down了一份,位址:https://github.com/greenrobot/eventbus,的确是個不錯的架構,主要用于事件的釋出和訂閱。

eventbus定義:是一個釋出 / 訂閱的事件總線。

這麼說應該包含4個成分:釋出者,訂閱者,事件,總線。

那麼這四者的關系是什麼呢?

很明顯:訂閱者訂閱事件到總線,發送者釋出事件。

大體應該是這樣的關系:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

訂閱者可以訂閱多個事件,發送者可以釋出任何事件,釋出者同時也可以是訂閱者。

好了,大體了解基本的關系以後,我們通過案例驅動來教大家如何使用;

相信大家對fragment都有所了解,現在我們的需求是這樣的,兩個fragment組成主界面,左邊的fragment是個目錄、即清單,右邊的fragment是詳細資訊面闆;

a、目錄的清單是從網絡擷取的。

b、當點選目錄上的條目時,動态更新詳細資訊面闆;

效果圖:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

看了這個需求,我們傳統的做法是:

a、目錄fragment在oncreate中去開啟線程去通路網絡擷取資料,擷取完成以後,通過handler去更新界面。

b、在目錄的fragment中提供一個接口,然後詳細資訊面闆去注冊這個接口,當發生點選時,去回調這個接口,讓詳細資訊面闆發生改變。

其實這種做法也還是不錯的,但是有了eventbus之後,我們互動會發生什麼樣的變化呢?拭目以待吧。

首先提一下:

eventbus.getdefault().register(this);//訂閱事件

eventbus.getdefault().post(object);//釋出事件

eventbus.getdefault().unregister(this);//取消訂閱

[java] view

plaincopy

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

package com.angeldevil.eventbusdemo;  

import android.os.bundle;  

import android.support.v4.app.fragmentactivity;  

public class mainactivity extends fragmentactivity  

{  

    @override  

    protected void oncreate(bundle savedinstancestate)  

    {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.activity_main);  

    }  

}  

[html] view

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

<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" />  

        android:id="@+id/item_detail_container"  

        android:name="com.angeldevil.eventbusdemo.itemdetailfragment"  

        android:layout_weight="2" />  

</linearlayout>  

可以看到,我們mainactvity可以說沒有一行代碼,布局檔案即兩個fragment組成;

首先看個實體類:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

import java.util.arraylist;  

import java.util.list;  

public class item  

    public string id;  

    public string content;  

    public static list<item> items = new arraylist<item>();  

    static  

        // add 6 sample items.  

        additem(new item("1", "item 1"));  

        additem(new item("2", "item 2"));  

        additem(new item("3", "item 3"));  

        additem(new item("4", "item 4"));  

        additem(new item("5", "item 5"));  

        additem(new item("6", "item 6"));  

    private static void additem(item item)  

        items.add(item);  

    public item(string id, string content)  

        this.id = id;  

        this.content = content;  

    public string tostring()  

        return content;  

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

import android.support.v4.app.listfragment;  

import android.view.view;  

import android.widget.arrayadapter;  

import android.widget.listview;  

import com.angeldevil.eventbusdemo.event.itemlistevent;  

import de.greenrobot.event.eventbus;  

public class itemlistfragment extends listfragment  

    public void oncreate(bundle savedinstancestate)  

        // register  

        eventbus.getdefault().register(this);  

    public void ondestroy()  

        super.ondestroy();  

        // unregister  

        eventbus.getdefault().unregister(this);  

    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()));  

    public void onlistitemclick(listview listview, view view, int position,  

            long id)  

        super.onlistitemclick(listview, view, position, id);  

        eventbus.getdefault().post(getlistview().getitematposition(position));  

itemlistfragment裡面在oncreate裡面進行了事件的訂閱,ondestroy裡面進行了事件的取消;onviewcreated中我們模拟了一個子線程去網絡加載資料,擷取成功後我們調用

了eventbus.getdefault().post(new itemlistevent(item.items));釋出了一個事件;

onlistitemclick則是listview的點選事件,我們調用了eventbus.getdefault().post(getlistview().getitematposition(position));去釋出一個事件,

getlistview().getitematposition(position)的類型為item類型;

細心的你一定發現了一些詭異的事,直接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()));

}

應該是這個方法為list綁定的資料。那麼這個方法是怎麼被調用的呢?

現在就可以細談訂閱事件與釋出事件了:

如果方法名以onevent開頭,則代表要訂閱一個事件,mainthread意思,這個方法最終要在ui線程執行;當事件釋出的時候,這個方法就會被執行。

那麼這個事件什麼時候釋出呢?

我們的oneventmainthread觸發時機應該在new thread()執行完成之後,可以看到子線程執行完成之後,執行了eventbus.getdefault().post(new itemlistevent(item.items));

意味着釋出了一個事件,當這個事件釋出,我們的oneventmainthread就執行了,那麼二者的關聯關系是什麼呢?

其實和參數的類型,我們oneventmainthread需要接收一個itemlistevent ,我們也釋出了一個itemlistevent的執行個體。

現在我們完整的理一下:

在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) ; 是不是呢?我們去看看。

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

import android.support.v4.app.fragment;  

import android.view.layoutinflater;  

import android.view.viewgroup;  

import android.widget.textview;  

public class itemdetailfragment extends fragment  

    private textview tvdetail;  

    /** list點選時會發送些事件,接收到事件後更新詳情 */  

    public void oneventmainthread(item item)  

        if (item != null)  

            tvdetail.settext(item.content);  

    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實參傳遞進來,我們更新控件。

這裡還有個事件類:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class event  

    /** 清單加載事件 */  

    public static class itemlistevent  

        private list<item> items;  

        public itemlistevent(list<item> items)  

            this.items = items;  

        }  

        public list<item> getitems()  

            return items;  

itemlistevent我們在itemlistfragment中使用的,作為的是oneventmainthread中的參數。為什麼封裝這麼個類呢?會在之後的eventbus源碼解析中說明。

到此我們的eventbus的初步用法就介紹完畢了。縱觀整個代碼,木有handler、木有asyntask,木有接口回調;but,我們像魔術般的實作了我們的需求;來告訴我,什麼是耦合,沒見到~~~

eventbus包含4個threadmode:postthread,mainthread,backgroundthread,async

mainthread我們已經不陌生了;我們已經使用過。

具體的用法,極其簡單,方法名為:oneventpostthread, oneventmainthread,oneventbackgroundthread,oneventasync即可

具體什麼差別呢?

oneventmainthread代表這個方法會在ui線程執行

oneventpostthread代表這個方法會在目前釋出事件的線程執行

backgroundthread這個方法,如果在非ui線程釋出的事件,則直接執行,和釋出在同一個線程中。如果在ui線程釋出的事件,則加入到一個背景的單線程隊列中去。

async 代表這個方法直接在獨立的線程中執行。

大家可以利用eventbus嘗試做以下操作:

當接收到某個廣播,例如短信,在界面上顯示。

開啟一個service,在伺服器裡面啟動一個定時線程,不斷更新activityui。

等等...之後,你會發現eventbus的魅力!

補充:

eventbus使用詳解(一)——初步使用eventbus

前言:eventbus是上周項目中用到的,網上的文章大都一樣,或者過時,有用的沒幾篇,經過琢磨,請教他人,也終于弄清楚點眉目,記錄下來分享給大家。

eventbus是一款針對android優化的釋出/訂閱事件總線。主要功能是替代intent,handler,broadcast在fragment,activity,service,線程之間傳遞消息.優點是開銷小,代碼更優雅。以及将發送者和接收者解耦。

1、下載下傳eventbus的類庫

源碼:https://github.com/greenrobot/eventbus

2、基本使用

(1)自定義一個類,可以是空類,比如:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class anyeventtype {  

     public anyeventtype(){}  

 }  

(2)在要接收消息的頁面注冊:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

eventbus.register(this);  

(3)發送消息

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

eventbus.post(new anyeventtype event);  

(4)接受消息的頁面實作(共有四個函數,各功能不同,這是其中之一,可以選擇性的實作,這裡先實作一個):

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public void onevent(anyeventtype event) {}  

(5)解除注冊

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

eventbus.unregister(this);  

順序就是這麼個順序,可真正讓自己寫,估計還是雲裡霧裡的,下面舉個例子來說明下。

首先,在eventbus中,擷取執行個體的方法一般是采用eventbus.getinstance()來擷取預設的eventbus執行個體,當然你也可以new一個又一個,個人感覺還是用預設的比較好,以防出錯。

先給大家看個例子:

當擊btn_try按鈕的時候,跳到第二個activity,當點選第二個activity上面的first event按鈕的時候向第一個activity發送消息,當第一個activity收到消息後,一方面将消息toast顯示,一方面放入textview中顯示。

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

按照下面的步驟,下面來建這個工程:

想必大家從一個activity跳轉到第二個activity的程式應該都會寫,這裡先稍稍把兩個activity跳轉的代碼建起來。後面再添加eventbus相關的玩意。

mainactivity布局(activity_main.xml)

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

    android:orientation="vertical">  

    <button   

        android:id="@+id/btn_try"  

        android:layout_width="match_parent"  

        android:layout_height="wrap_content"  

        android:text="btn_bty"/>  

    <textview   

        android:id="@+id/tv"  

        android:layout_width="wrap_content"  

        android:layout_height="match_parent"/>  

建立一個activity,secondactivity布局(activity_second.xml)

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

    android:orientation="vertical"  

    tools:context="com.harvic.try_eventbus_1.secondactivity" >  

        android:id="@+id/btn_first_event"  

        android:text="first event"/>  

mainactivity.java (點選btn跳轉到第二個activity)

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class mainactivity extends activity {  

    button btn;  

    protected void oncreate(bundle savedinstancestate) {  

        btn = (button) findviewbyid(r.id.btn_try);  

        btn.setonclicklistener(new view.onclicklistener() {  

            @override  

            public void onclick(view v) {  

                // todo auto-generated method stub  

                intent intent = new intent(getapplicationcontext(),  

                        secondactivity.class);  

                startactivity(intent);  

            }  

        });  

到這,基本架構就搭完了,下面開始按步驟使用eventbus了。

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

package com.harvic.other;  

public class firstevent {  

    private string mmsg;  

    public firstevent(string msg) {  

        // todo auto-generated constructor stub  

        mmsg = msg;  

    public string getmsg(){  

        return mmsg;  

這個類很簡單,構造時傳進去一個字元串,然後可以通過getmsg()擷取出來。

在上面的gif圖檔的示範中,大家也可以看到,我們是要在mainactivity中接收發過來的消息的,是以我們在mainactivity中注冊消息。

通過我們會在oncreate()函數中注冊eventbus,在ondestroy()函數中反注冊。是以整體的注冊與反注冊的代碼如下:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

package com.example.tryeventbus_simple;  

import com.harvic.other.firstevent;  

import android.app.activity;  

import android.content.intent;  

import android.util.log;  

import android.widget.button;  

import android.widget.toast;  

    textview tv;  

                //注冊eventbus  

        tv = (textview)findviewbyid(r.id.tv);  

    protected void ondestroy(){  

        eventbus.getdefault().unregister(this);//反注冊eventbus  

發送消息是使用eventbus中的post方法來實作發送的,發送過去的是我們建立的類的執行個體!

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

eventbus.getdefault().post(new firstevent("firstevent btn clicked"));  

完整的secondactivity.java的代碼如下:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class secondactivity extends activity {  

    private button btn_firstevent;  

        setcontentview(r.layout.activity_second);  

        btn_firstevent = (button) findviewbyid(r.id.btn_first_event);  

        btn_firstevent.setonclicklistener(new view.onclicklistener() {  

                eventbus.getdefault().post(  

                        new firstevent("firstevent btn clicked"));  

接收消息時,我們使用eventbus中最常用的oneventmainthread()函數來接收消息,具體為什麼用這個,我們下篇再講,這裡先給大家一個初步認識,要先能把eventbus用起來先。

在mainactivity中重寫oneventmainthread(firstevent event),參數就是我們自己定義的類:

在收到event執行個體後,我們将其中攜帶的消息取出,一方面toast出去,一方面傳到textview中;

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public void oneventmainthread(firstevent event) {  

    string msg = "oneventmainthread收到了消息:" + event.getmsg();  

    log.d("harvic", msg);  

    tv.settext(msg);  

    toast.maketext(this, msg, toast.length_long).show();  

完整的mainactiviy代碼如下:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

    public void oneventmainthread(firstevent event) {  

        string msg = "oneventmainthread收到了消息:" + event.getmsg();  

        log.d("harvic", msg);  

        tv.settext(msg);  

        toast.maketext(this, msg, toast.length_long).show();  

好了,到這,基本上算初步把eventbus用起來了,下篇再講講eventbus的幾個函數,及各個函數間是如何識别目前如何調用哪個函數的。

源碼位址:http://download.csdn.net/detail/harvic880925/8111357

請大家尊重原創者版權,轉載請标明出處:http://blog.csdn.net/harvic880925/article/details/40660137  

謝謝!

eventbus使用詳解(二)——eventbus使用進階

前言:這段時間感覺自己也有點懶了,真是内心有點自責呢,除了工作,也沒做點什麼,eventbus也是一周前總結出來的,隻能以寫部落格為名來彌補内心的罪惡感了,集合同僚們做的項目,雖然上周開動了,但總感覺大家積極性不高,如何才能做一個合格的管理者,還真是一個考驗。follow your heart!! just do it!

前一篇給大家裝簡單示範了eventbus的oneventmainthread()函數的接收,其實eventbus還有另外有個不同的函數,他們分别是:

1、onevent

2、oneventmainthread

3、oneventbackgroundthread

4、oneventasync

這四種訂閱函數都是使用onevent開頭的,它們的功能稍有不同,在介紹不同之前先介紹兩個概念:

告知觀察者事件發生時通過eventbus.post函數實作,這個過程叫做事件的釋出,觀察者被告知事件發生叫做事件的接收,是通過下面的訂閱函數實作的。

onevent:如果使用onevent作為訂閱函數,那麼該事件在哪個線程釋出出來的,onevent就會在這個線程中運作,也就是說釋出事件和接收事件線程在同一個線程。使用這個方法時,在onevent方法中不能執行耗時操作,如果執行耗時操作容易導緻事件分發延遲。

oneventmainthread:如果使用oneventmainthread作為訂閱函數,那麼不論事件是在哪個線程中釋出出來的,oneventmainthread都會在ui線程中執行,接收事件就會在ui線程中運作,這個在android中是非常有用的,因為在android中隻能在ui線程中跟新ui,是以在onevnetmainthread方法中是不能執行耗時操作的。

oneventbackground:如果使用oneventbackgrond作為訂閱函數,那麼如果事件是在ui線程中釋出出來的,那麼oneventbackground就會在子線程中運作,如果事件本來就是子線程中釋出出來的,那麼oneventbackground函數直接在該子線程中執行。

oneventasync:使用這個函數作為訂閱函數,那麼無論事件在哪個線程釋出,都會建立新的子線程在執行oneventasync.

上面列出的這四個函數,關鍵問題在于,我們怎麼指定調用哪個函數呢?

我們先研究一下,上一篇中是怎麼調用的oneventmainthread函數,除了在接收端注冊與反注冊以後,關鍵問題在于建立的一個類:

建立一個類:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

發送時:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

eventbus.getdefault().post(new firstevent("firstevent btn clicked"));    

接收時:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public void oneventmainthread(firstevent event) {    

    ……  

}    

發現什麼問題了沒?

沒錯,發送時發送的是這個類的執行個體,接收時參數就是這個類執行個體。

是以!!!!!!當發過來一個消息的時候,eventbus怎麼知道要調哪個函數呢,就看哪個函數傳進去的參數是這個類的執行個體,哪個是就調哪個。那如果有兩個是呢,那兩個都會被調用!!!!

為了證明這個問題,下面寫個例子,先看下效果

先看看我們要實作的效果:

這次我們在上一篇的基礎上,建立三個類:firstevent、secondevent、thirdevent,在第二個activity中發送請求,在mainactivity中接收這三個類的執行個體,接收時的代碼為:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

    log.d("harvic", "oneventmainthread收到了消息:" + event.getmsg());  

public void oneventmainthread(secondevent event) {  

public void onevent(thirdevent event) {  

    log.d("harvic", "onevent收到了消息:" + event.getmsg());  

使用兩個oneventmainthread分别接收firstevent執行個體的消息和secondevent執行個體的消息,使用onevent接收thirdevent執行個體的消息。界面操作及結果如下:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

log輸出結果:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

可以看到,在發送firstevent時,在mainactiviy中雖然有三個函數,但隻有第一個oneventmainthread函數的接收參數是firstevent,是以會傳到它這來接收。是以這裡識别調用eventbus中四個函數中哪個函數,是通過參數中的執行個體來決定的。

因為我們是在上一篇例子的基礎上完成的,是以這裡的代碼就不詳細寫了,隻寫改動的部分。

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class secondevent{  

    public secondevent(string msg) {  

        mmsg = "mainevent:"+msg;  

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

public class thirdevent {  

    public thirdevent(string msg) {  

然後在secondactivity中建立三個按鈕,分别發送不同的類的執行個體,代碼如下:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

package com.harvic.tryeventbus2;  

import com.harvic.other.secondevent;  

import com.harvic.other.thirdevent;  

    private button btn_firstevent, btn_secondevent, btn_thirdevent;  

        btn_secondevent = (button) findviewbyid(r.id.btn_second_event);  

        btn_thirdevent = (button) findviewbyid(r.id.btn_third_event);  

        btn_secondevent.setonclicklistener(new view.onclicklistener() {  

                        new secondevent("secondevent btn clicked"));  

        btn_thirdevent.setonclicklistener(new view.onclicklistener() {  

                        new thirdevent("thirdevent btn clicked"));  

在mainactivity中,除了注冊與注冊,我們利用oneventmainthread(firstevent event)來接收來自firstevent的消息,使用oneventmainthread(secondevent event)接收來自secondevent 執行個體的消息,使用onevent(thirdevent event) 來接收thirdevent

執行個體的消息。

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

import android.view.menu;  

import android.view.menuitem;  

    eventbus eventbus;  

        log.d("harvic", "oneventmainthread收到了消息:" + event.getmsg());  

    public void oneventmainthread(secondevent event) {  

    public void onevent(thirdevent event) {  

        log.d("harvic", "onevent收到了消息:" + event.getmsg());  

    protected void ondestroy() {  

        // todo auto-generated method stub  

到這裡,代碼就結束 了,從上面的代碼,我們可以看到,eventbus是怎麼接收消息的,是根據參數中類的執行個體的類型的判定的,是以當如果我們在接收時,同一個類的執行個體參數有兩個函數來接收會怎樣?答案是,這兩個函數都會執行,下面實驗一下:

在mainactivity中接收時,我們在接收secondevent時,在上面oneventmainthread基礎上另加一個oneventbackgroundthread和oneventasync,即下面的代碼:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

//secondevent接收函數一  

//secondevent接收函數二  

public void oneventbackgroundthread(secondevent event){  

    log.d("harvic", "oneventbackground收到了消息:" + event.getmsg());  

//secondevent接收函數三  

public void oneventasync(secondevent event){  

    log.d("harvic", "oneventasync收到了消息:" + event.getmsg());  

完整的代碼在這裡:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話
Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

    //secondevent接收函數一  

    //secondevent接收函數二  

    public void oneventbackgroundthread(secondevent event){  

        log.d("harvic", "oneventbackground收到了消息:" + event.getmsg());  

    //secondevent接收函數三  

    public void oneventasync(secondevent event){  

        log.d("harvic", "oneventasync收到了消息:" + event.getmsg());  

經過上面的分析,當發送secondevent執行個體的消息過來的時候,這三個函數會同時接收到并各自執行,是以當點選second event這個button的時候,會出現下面的結果:

Android EventBus實戰 轉載自:http://blog.csdn.net/lmj623565791/article/details/40794879 1、概述 2、代碼是最好的老師 3、EventBus的ThreadMode 4、題外話

好啦,這篇就到了,講來講去就是說一個問題:消息的接收是根據參數中的類名來決定執行哪一個的;

參考文章:

《android解耦庫eventbus的使用和源碼分析》:http://blog.csdn.net/yuanzeyao/article/details/38174537

《eventbus的使用初試》:http://blog.csdn.net/pp_hdsny/article/details/14523561

《eventbusexplained 》:https://code.google.com/p/guava-libraries/wiki/eventbusexplained

《google

guava eventbus執行個體與分析》

如果我的文章有幫到你,記得關注哦!

源碼下載下傳位址:http://download.csdn.net/detail/harvic880925/8128633

請大家尊重原創者版權,轉載請标明出處:http://blog.csdn.net/harvic880925/article/details/40787203  

繼續閱讀