EventBus是一個Android端優化的publish/subscribe消息總線,簡化了應用程序內各組件間、組件與后臺線程間的通訊,比如網絡請求,等網絡返回時通過Handler或Broadcast通知UI,兩個Fragment之間需要通過Listener通信,這些需求都可以通過EventBus實現。
Github地址: https://github.com/greenrobot/EventBus
在build.gradle里面添加
compile 'org.greenrobot:eventbus:3.0.0'在需要接收消息的activity里面進行注冊
EventBus.getDefault().register(MainActivity.this);對應的activity銷毀了就解注冊EventBus,釋放內存
/** * 解注冊EventBus */@OverridePRotected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(MainActivity.this);}新建一個類,這里取名為MessageEvent,用來做消息的傳遞。 這個類可以是自定義或者你用String這些也行,發送和接收的類型一定要一致才能接收到
/** * EventBus發送信息類 */public class MessageEvent { String name; public MessageEvent(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }}這個post的參數類型一定要和接收消息的類型一致
public void sendEventBusMessage(){ EventBus.getDefault().post(new MessageEvent("天平"));}在注冊了的activity里面編寫方法接收消息,必須加注解Subscribe,threadMode在下面會說到。 接收消息的方法名沒有限制。
/** * 5.接收消息,需要加注解Subscribe訂閱者 * @param bean 自定義的消息類,根據這個類標識來接收 */@Subscribe(threadMode = ThreadMode.MAIN)public void receiverEvenetBusMess(MessageEvent bean){ //顯示接收到的消息 Toast.makeText(this,bean.getName()+"",Toast.LENGTH_SHORT).show();}前面所說的使用方法都是需要先注冊register,再post,才能接收到事件;如果你使用postSticky發送事件,那么可以不需要先注冊,你先postSticky之后,再注冊也能接收到事件。
3.4 注冊 3.5 解注冊
注冊和解注冊和上面的一致
在接收的方法上面需要添加注解來接收消息,注解可以添加的參數有三個
線程模式,接收消息的你這個方法是不是在線程,在注解上面標識:
/** * 5.接收消息,需要加注解Subscribe訂閱者,參數類型必須和發送時候類型一致才能接收, * @param bean */@Subscribe(threadMode = ThreadMode.MAIN)public void receiverEvenetBusMess(MessageEvent bean){ //顯示接收到的消息 Toast.makeText(this,bean.getName()+"",Toast.LENGTH_SHORT).show(); tvResult.setText(bean.getName());}有四種消息類型 1. ThreadMode.MAIN 表示這個方法在主線程中執行,不能處理耗時任務噢,一般用來更新UI,因為更新ui需要在ui線程中。。。。
ThreadMode.BACKGROUND 當事件是在UI線程發出,那么事件處理實際上是新建了一個單獨線程回調,如果是在后臺線程發出,那么事件處理就在該線程。該事件處理方法應該是快速的,避免阻塞后臺線程。
ThreadMode.ASYNC 無論事件在哪個線程發布,都會創建新的子線程在執行,發送事件方不需要等待事件處理完畢。這種方式適用于該事件處理方法需要較長時間,例如網絡請求。
ThreadMode.POSTING (注解不設置的threadMode的話,默認就是這個模式) 消息在哪個線程發布出來的,接收的方法就會在這個線程中運行,也就是說發布事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操作,如果執行耗時操作容易導致事件分發延遲。
是否是粘性,默認值為假。在粘性事件用到,接收方法的注解上面需要添加這個參數為true,才能收到消息。例如:
/** * 接收粘性事件,sticky為true * @param bean 接收到的消息 */@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)public void receiverStickyMess(StickyMessageEvent bean){ tvResult.setText(bean.getAge()+""); Toast.makeText(this,bean.getAge()+"",Toast.LENGTH_SHORT).show();}優先級,默認值為0,就是你有多個接收的方法,這時候你可以指定接收的順序,添加參數priority。值越大,越先收到,從大到小 依次接收。例如:
/** * 5.接收消息,需要加注解Subscribe訂閱者,參數類型必須和發送時候類型一致才能接收, * @param bean */ @Subscribe(threadMode = ThreadMode.MAIN,priority = 0) public void receiverEvenetBusMess(MessageEvent bean){ //顯示接收到的消息 //Toast.makeText(this,bean.getName()+"111",Toast.LENGTH_SHORT).show(); tvResult.setText( tvResult.getText() + "/n" + bean.getName() + "000"); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 2) public void receiverEvenetBusMessTwo(MessageEvent bean){ //顯示接收到的消息 //Toast.makeText(this,bean.getName()+"222",Toast.LENGTH_SHORT).show(); tvResult.setText( tvResult.getText() + "/n" + bean.getName() + "222"); } @Subscribe(threadMode = ThreadMode.MAIN,priority = 1) public void receiverEvenetBusMessThree(MessageEvent bean){ //顯示接收到的消息 //Toast.makeText(this,bean.getName()+"222",Toast.LENGTH_SHORT).show(); tvResult.setText( tvResult.getText() + "/n" + bean.getName() + "111"); }上面的代碼輸出結果是:
天平222天平111天平000創建一個事件類,把你的每一個參數(或者可能發生沖突的參數),封裝成一個類:
public class EventBean { public static class UserListEvent { public List<User> users; } public static class ItemListEvent { public List<Item> items; } }按照Markus Junginger的說法(EventBus創作者),在3.0中,如果你想進一步提升你的app的性能,需要在build.gradle添加:
provided 'de.greenrobot:eventbus-annotation-processor:3.0.0'其在編譯的時候為注冊類構建了一個索引,而不是在運行時,這樣的結果是其讓EventBus 3.0的性能提升了一倍,相比2.4來說,其會是它的3到6倍。
官方說明: http://greenrobot.org/eventbus/documentation/proguard/
新聞熱點
疑難解答