EventBus是一個第三方開源框架。它的作用主要是解決各組件、組件與後臺線程間的信息溝通問題。
比如,如何在Activity_B中修改Activity_A中的TextView顯示信息?
之前的做法是:接口回調或者通過廣播。現在只需要通過EventBus就可以輕鬆解決,主要是爲了項目的解耦。
EventBus項目地址:https://github.com/greenrobot/EventBus
EventBus和廣播有點類似,需要Event事件、事件訂閱者、事件發佈者三項。
EventBus有四種線程模型,分別是:
- POSTING (默認) 表示事件處理函數的線程跟發佈事件的線程在同一個線程。
- MAIN 表示事件處理函數的線程在主線程(UI)線程,因此在這裏不能進行耗時操作。
- BACKGROUND 表示事件處理函數的線程在後臺線程,因此不能進行UI操作。如果發佈事件的線程是主線程(UI線程),那麼事件處理函數將會開啓一個後臺線程,如果果發佈事件的線程是在後臺線程,那麼事件處理函數就使用該線程。
- ASYNC 表示無論事件發佈的線程是哪一個,事件處理函數始終會新建一個子線程運行,同樣不能進行UI操作。
基本使用步驟如下:
(1)添加遠程依賴:
implementation 'org.greenrobot:eventbus:3.1.1'
(2)自定義一個事件類(泛型)
/** * 事件類(泛型) * @param <T> */ public class MessageEvent<T> { private T message; public MessageEvent(T message) { this.message = message; } public T getMessage() { return message; } public void setMessage(T message) { this.message = message; } }
(3)在OneActivity.java中註冊事件以及解除註冊事件,代碼如下:
public class OneActivity extends BaseActivity implements View.OnClickListener { private Context mContext; private TextView tvInfo; private Button btnJump; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_eventbus_one); baseDataInit(); bindViews(); viewsAddListener(); viewsDataInit(); EventBus.getDefault().register(this); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } @Subscribe(threadMode = ThreadMode.MAIN) public void alertInfo(MessageEvent messageEvent) { tvInfo.setText(((Tb_MessageInfo)messageEvent.getMessage()).getName()); } @Override public void baseDataInit() { mContext = this; } @Override public void bindViews() { tvInfo = findViewById(R.id.EventBus_One_tvInfo); btnJump = findViewById(R.id.EventBus_One_btnSwitch); } @Override public void viewsAddListener() { btnJump.setOnClickListener(this::onClick); } @Override public void viewsDataInit() { tvInfo.setText("信息顯示"); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.EventBus_One_btnSwitch: { //EventBus.getDefault().postSticky(new MessageEvent("發送粘性事件內容用於EditText顯示")); startActivity(new Intent(mContext, TwoActivity.class)); break; } default:break; } } }
備註:主要是那個處理事件代碼如下:
@Subscribe(threadMode = ThreadMode.MAIN) public void alertInfo(MessageEvent messageEvent) { tvInfo.setText(((Tb_MessageInfo)messageEvent.getMessage()).getName()); }
(4)在TwoActivity.java中發佈事件,代碼如下:
public class TwoActivity extends BaseActivity implements View.OnClickListener { private Context mContext; private EditText etContent; private Button btnSubmit; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_eventbus_two); baseDataInit(); bindViews(); viewsAddListener(); viewsDataInit(); //EventBus.getDefault().register(this); } @Override protected void onDestroy() { super.onDestroy(); //EventBus.getDefault().unregister(this); } /*@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void editTextShow(MessageEvent messageEvent) { etContent.setText(messageEvent.getMessage()); }*/ @Override public void baseDataInit() { mContext = this; } @Override public void bindViews() { etContent = findViewById(R.id.EventBus_Two_etContent); btnSubmit = findViewById(R.id.EventBus_Two_btnSubmit); } @Override public void viewsAddListener() { btnSubmit.setOnClickListener(this::onClick); } @Override public void viewsDataInit() { } @Override public void onClick(View v) { switch (v.getId()) { case R.id.EventBus_Two_btnSubmit: { String name = etContent.getText().toString().trim(); EventBus.getDefault().post(new MessageEvent<Tb_MessageInfo>(new Tb_MessageInfo(name, "17"))); finish(); break; } default:break; } } }
備註:主要是那個發佈事件代碼如下:
EventBus.getDefault().post(new MessageEvent<Tb_MessageInfo>(new Tb_MessageInfo(name, "17")));
PS:還有一種是粘性事件,它主要是A界面事件已發佈,進入B界面,但是B界面還想收到該事件的情況下進行處理的。(說白了,就是消息已發佈,但是還沒有人註冊,沒人收得到。)和普通事件有兩點區別:
(1)處理事件的方法加了,sticky=true,代碼如下:
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true) public void editTextShow(MessageEvent messageEvent) { etContent.setText(((Tb_MessageInfo)messageEvent.getMessage()).getName()); }
(2)發佈事件的方法也變了,代碼如下:
EventBus.getDefault().postSticky(new MessageEvent<Tb_MessageInfo>(new Tb_MessageInfo("張三", "17")));