爲什麼要用EventBus?它是幹什麼用的?
EventBus是什麼
EventBus是一個Android端優化的publish/subscribe消息總線,簡化了應用程序內各組件間、組件與後臺線程間的通信。
這樣一個簡單的概念,可能讓你不足以感受到EventBus的魅力。我們來思考一下下面這些情況。
使用購物類APP時,我們在商品詳情頁將商品加入購物車時,底部tab欄的購物車tab右上角的小數字也同步發生了變化。
面對這樣的需求,一般情況下都是在詳情頁中提供一個接口,在tab欄所在的Activity(或者是Fragment)中註冊這個接口,當點擊事件發生是,回調這個接口,更新tab欄的內容。甚至有時候,由於我們的應用會是Activity+多個fragment 的組合,可能需要多個接口經過層層傳遞,才能實現某些在產品經理看來很簡單的UI更新。
大部分APP在用戶完成用戶登錄操作後,需要在返回界面同步更新用戶信息。
這個時候,我們一般會在返回界面的onActivityResult方法中,通過requestCode及resultCode做出種種判斷,最後在確認用戶登錄成功的情況下,請求用戶信息完成UI的更新,這種體驗其實是非常不好,作爲一個用戶希望的是,登錄成功的同時完成用戶信息的更新。
當然上面兩種情況,用BroadcastReceiver實現,也是完全可以的,肯能會相對簡單一些,但是從整體性能來說,這樣是不好的;再者古人云,殺雞焉用牛刀!!!
而EventBus的出現,很好的解決了這些讓我們頭疼的問題。首先就用一個簡單的列子來實現一下用戶登錄信息異步更新的情況。
EventBus 3.0 使用Demo
這裏用兩個Activity簡單的模擬常見的用戶登錄。效果圖如下
用戶信息界面
public class FirstActivity extends AppCompatActivity {
private Button btn;
private Context mContext;
//User Info
private TextView userName;
private ImageView usreImg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
EventBus.getDefault().register(mContext);
InitView();
}
private void InitView() {
setContentView(R.layout.activity_first);
userName = (TextView) findViewById(R.id.userName);
usreImg = (ImageView) findViewById(R.id.userImg);
btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(mContext, SecondActivity.class));
}
});
}
@Subscribe
public void onUserEvent(UserEvent event) {
userName.setText("用戶名:" + event.nameStr);
Glide.with(mContext).load(event.imgUrl).into(usreImg);
}
@Override
protected void onDestroy() {
EventBus.getDefault().unregister(mContext);
super.onDestroy();
}
}
用戶登錄界面
public class SecondActivity extends AppCompatActivity {
private Context mContext;
private Button btn;
private EditText name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext=this;
setContentView(R.layout.activity_second);
name = (EditText) findViewById(R.id.name);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//測試數據
String userImg = "http://img2.imgtn.bdimg.com/it/u=262221958,4109901128&fm=21&gp=0.jpg";
//這裏只是爲了方便測試,隨便寫的登錄邏輯
String userName="";
if(!TextUtils.isEmpty(name.getText().toString())){
userName = name.getText().toString();
UserEvent userEvent = new UserEvent(userName, userImg);
EventBus.getDefault().post(userEvent);
}else {
//不再發送事件Event
Toast.makeText(mContext,"登錄失敗",Toast.LENGTH_SHORT).show();
}
finish();
}
});
}
}
UserEvent 類
public class UserEvent {
public final String nameStr;
public final String imgUrl;
public UserEvent(String nameStr, String imgUrl) {
this.nameStr = nameStr;
this.imgUrl = imgUrl;
}
}
這裏可以看到沒有Handler,沒有onActivityResult的判斷,沒有沒有任何接口。就實現瞭如gif圖中所示效果。
接下來,就總結一下如何使用EventBus3.0 。
EventBus 3.0 使用步驟
1.首先我們需要將EventBus添加到我們的項目中。在AndroidStudio中我們可以在gradle裏面直接配置即可。
compile 'org.greenrobot:eventbus:3.0.0'
2.創建一個事件類(這個類似於JavaBean),就是上面的UserEvent類。
這裏的Demo只是舉例說明簡單用法,實際中可以根據需要創建不同的事件類
3.註冊
EventBus.getDefault().register(mContext);
4.訂閱(響應事件方法)
@Subscribe
public void onUserEvent(UserEvent event) {
userName.setText("用戶名:" + event.nameStr);
Glide.with(mContext).load(event.imgUrl).into(usreImg);
}
這裏的註解@Subscribe 很關鍵,表明這個方法爲訂閱者,這個方法的名字也已經不在重要了(相對於以前的版本來說),在這個方法裏,我們實現了UI更新,將用戶信息更新出來。
5.分發事件
UserEvent userEvent = new UserEvent(userName, userImg);
EventBus.getDefault().post(userEvent);
6.解除註冊
EventBus.getDefault().unregister(mContext);
這裏僅從一個最簡單的Demo,瞭解了一下EventBus是多麼的神奇。此處沒有網絡請求,post方法也是在主線程中,所以默認情況下相應事件方法onUserEvent也會在主線程中執行。實際上onUserEvent方法在註解中還是需要添加參數的。
好了,這裏就簡單瞭解一下EventBus3.0 ,下篇文章就其使用方法深入瞭解一下。