EventBus是一款針對Android優化的發佈/訂閱事件總線。能夠替代廣播、startActivityForResult、Handler、異步回調等來實現各組件間、組件與後臺線程間的通訊。它的優勢是開銷小,代碼更優雅,以及將發送者和接收者解耦。css
一般咱們在使用EventBus的時候都是直接須要接收通訊的Activity/Fragment中經過EventBus.getDefault().register(this)訂閱事件,在須要發起通訊的邏輯直接調用EventBus.getDefault().post(Object event)來發布事件。可是要是一個項目中有不少地方都使用EventBus來通訊,好比從新登陸後更新各個頁面的登陸狀態,或者是接收到通知更新消息提示等,都這樣直接使用的話代碼重複率很高,而且呢,若是之後升級或者更換EventBus時,各個地方都要修改,這就比較麻煩了。所以我通常是將EventBus的發佈和訂閱封裝到BaseActivity/BaseFragment中。
git
gitHub地址github
implementation 'org.greenrobot:eventbus:3.1.1'
EventBus3.0有四種線程模型,分別是:異步
public class EventMessage<T> { private int code;//消息類型 private T data;//消息數據 public EventMessage(int code,T data){ this.code=code; this.data=data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return "EventMessage{" + "code=" + code + ", data=" + data + '}'; } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); }
@Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); }
//普通事件 EventBus.getDefault().post(event); //粘性事件 EventBus.getDefault().postSticky(event);
//普通事件處理
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveEvent(EventMessage msg){
//處理事件
}
//粘性事件處理
@Subscribe(threadMode = ThreadMode.MAIN,sticky=true)
public void onReceiveStickyEvent(EventMessage msg){
//事件處理
}
事件EventMessage:ide
public class EventMessage<T> { private int code;//消息類型 private T data;//消息數據 public EventMessage(int code,T data){ this.code=code; this.data=data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public T getData() { return data; } public void setData(T data) { this.data = data; } @Override public String toString() { return "EventMessage{" + "code=" + code + ", data=" + data + '}'; } }
事件類型:EventCode:函數
/** * 消息類型 */ public class EventCode { //根據具體業務定義類型 public static final int EVENT_A=1000; public static final int EVENT_B=1001; public static final int EVENT_C=1002; public static final int EVENT_D=1003; public static final int EVENT_E=1004; }
EventBus封裝:佈局
public class EventBusUtils { private EventBusUtils(){ } /** * 註冊EventBus * @param subscribver */ public static void register(Object subscribver){ EventBus eventBus=EventBus.getDefault(); if(!eventBus.isRegistered(subscribver)){ eventBus.register(subscribver); } } /** * 解除註冊EventBus * @param subscriber */ public static void unregister(Object subscriber){ EventBus eventBus=EventBus.getDefault(); if(eventBus.isRegistered(subscriber)){ eventBus.unregister(subscriber); } } /** * 發送普通事件消息 */ public static void post(Object event){ EventBus.getDefault().post(event); } /** * 發送粘性事件消息 */ public static void postSticky(Object event){ EventBus.getDefault().postSticky(event); } /** * 移除全部的粘性訂閱事件 */ public static void removeAllStickyEvents(){ EventBus.getDefault().removeAllStickyEvents(); } }
案例:從MainActivity分別跳轉FirstActivity和SecondActivity,跳轉SecondActivity時發送粘性事件,返回到MainActivity時發送普通事件post
代碼實戰:優化
BaseActivity:this
public abstract class BaseActivity extends AppCompatActivity { private String TAG="BaseActivity"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutResId()); initView(); initData(); if(isRegisteredEventBus()){//放到initView後面 防止 接收到event事件須要更新UI的時候 佈局還未初始化完成 EventBusUtils.register(this); } } @Override protected void onDestroy() { release(); if(isRegisteredEventBus()){ EventBusUtils.unregister(this); } super.onDestroy(); } /** * 獲取佈局 * @return 佈局ID */ protected abstract int getLayoutResId(); /** * 初始化視圖 */ protected void initView(){} /** * 初始化數據 */ protected void initData(){} /** * 釋放資源 */ protected void release(){} /** * 是否註冊事件分發 * @return true:註冊 false:不註冊 默認不註冊 */ protected boolean isRegisteredEventBus(){ Log.e(TAG, "isRegisteredEventBus: 00000"); return false; } }
MainActivity:
public class MainActivity extends BaseActivity implements View.OnClickListener { private String TAG="MainActivity"; private TextView tv; private Button bt1,bt2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected int getLayoutResId() { return R.layout.activity_main; } @Override protected void initView() { super.initView(); tv=findViewById(R.id.tv); bt1=findViewById(R.id.bt1); bt2=findViewById(R.id.bt2); bt1.setOnClickListener(this); bt2.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt1: FirstActivity.startActivity(MainActivity.this); break; case R.id.bt2: EventMessage eventMessage=new EventMessage(EventCode.EVENT_E,"來自mainactivity的msg"); EventBusUtils.postSticky(eventMessage); SecondActivity.startActivity(MainActivity.this); break; } } @Subscribe(threadMode = ThreadMode.MAIN) public void onReceiveEvent(EventMessage msg){ String m=(String) msg.getData(); if(msg.getCode()==EventCode.EVENT_A){ tv.setText(m); }else if(msg.getCode()==EventCode.EVENT_B){ tv.setText(m); } } @Override protected boolean isRegisteredEventBus() { Log.e(TAG, "isRegisteredEventBus: 1111" ); return true; } }
FirstActivity:
public class FirstActivity extends BaseActivity implements View.OnClickListener { private String TAG="FirstActivity"; private TextView tv; private Button bt; /** * 啓動activity */ public static void startActivity(Activity srcActivity) { Intent intent=new Intent(srcActivity,FirstActivity.class); srcActivity.startActivity(intent); } @Override protected int getLayoutResId() { return R.layout.activity_first; } @Override protected void initView() { super.initView(); tv=findViewById(R.id.tv); bt=findViewById(R.id.bt1); bt.setOnClickListener(this); } @Override protected void initData() { super.initData(); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt1: EventMessage msg=new EventMessage(EventCode.EVENT_A,"來自firstactivity的消息"); EventBusUtils.post(msg); this.finish(); break; } } }
SecondActivity:
public class SecondActivity extends BaseActivity implements View.OnClickListener { private String TAG="SecondActivity"; private TextView tv; private Button bt; public static void startActivity(Activity activity){ Intent intent=new Intent(activity,SecondActivity.class); activity.startActivity(intent); } @Override protected int getLayoutResId() { return R.layout.activity_second; } @Override protected void initView() { super.initView(); tv=findViewById(R.id.tv); bt=findViewById(R.id.bt1); bt.setOnClickListener(this); } @Override protected void initData() { super.initData(); } @Override protected boolean isRegisteredEventBus() { return true; } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt1: EventMessage msg=new EventMessage(EventCode.EVENT_B,"來自secondactivity的消息"); EventBusUtils.post(msg); this.finish(); break; } } @Subscribe(threadMode = ThreadMode.MAIN,sticky=true) public void onReceiveEvent(EventMessage msg){ Log.e(TAG, "onReceiveEvent: msg:"+msg.toString() ); if (msg.getCode()==EventCode.EVENT_E){ tv.setText((String)msg.getData()); } } }
1.在基類中封裝時,注意註冊EventBus放到初始化視圖後面,防止收到粘性事件須要更新UI時 佈局還未初始化玩 會報空指針異常