EventBus是什么?
EventBus由greenrobot組織貢獻(該組織還貢獻了greenDAO),一個Android事件發布/訂閱輕量級框架,下面來一張圖作為說明。
EventBus有什么用?
我們可以通過解耦發布者和訂閱者簡化Android事件傳遞。
EventBus可以代替Android傳統的Intent,Handler,Broadcast或接口函數,在Fragment,Activity,Service線程之間傳遞數據,執行方法。
使代碼簡單
快,高性能:特別是在注重性能的Android上。也許在其同類的解決方案是最快的。
小(jar包小于50K),但是強大:EventBus是一個很小的庫,它的API超級簡單。
android主線程傳遞:當和UI交互的時候,無論這個事件是怎么提交的,EventBus都可以在主線程傳遞事件。
如何使用
首先在你的項目中添加eventbus的依賴
compile 'org.greenrobot:eventbus:3.0.0'
這里給大家舉一個例子,MainActivity打開CommonActivity,在CommonActivity發出一個事件,然后MainActivity做出相應的反饋。
package cn.lxt.stickeventbus;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//首先要在你要接受EventBus的界面注冊,這一步很重要
EventBus.getDefault().register(this);
Button btnCommon = (Button) findViewById(R.id.btn_common);
btnCommon.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_common:
//點擊按鈕進入CommonActivity
CommonActivity.start(this);
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//在界面銷毀的地方要解綁
EventBus.getDefault().unregister(this);
}
//任意寫一個方法,給這個方法一個@Subscribe注解,參數類型可以自定義,但是一定要與你發出的類型相同
@Subscribe
public void getEventBus(Integer num) {
if (num != null) {
//這里拿到事件之后吐司一下
Toast.makeText(this, "num" + num, Toast.LENGTH_SHORT).show();
}
}
}
接下來就是在CommonActivity里面
package cn.lxt.stickeventbus;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import org.greenrobot.eventbus.EventBus;
/**
* Created by Administrator on 2017/8/16 0016.
*/
public class CommonActivity extends AppCompatActivity implements View.OnClickListener {
public static void start(Context context) {
context.startActivity(new Intent(context, CommonActivity.class));
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common);
Button button = (Button) findViewById(R.id.btn_send);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
//點擊按鈕,發送一個int類型的事件
EventBus.getDefault().post(666);
finish();
break;
}
}
}
接下來給大家看效果圖
大家可以清晰的看到,666彈出來了。當然,EventBus之所以好用,自然有他的強大之處,比如說,我在子線成發送的消息,在接受的地方切換到主線程,只需要增加一個參數即可,那么接下來就要說到線程模式了。
線程模式
我們把發送消息放到子線程,把接收消息放到主線程并且更新UI。
CommonActivity 里面發送消息放到子線程
new Thread(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(666);
finish();
}
}).start();
MainActivity里面接收事件,只需要指定線程模式即可,即threadMode = ThreadMode.MAIN
@Subscribe(threadMode = ThreadMode.MAIN)
public void getEventBus(Integer num) {
if (num != null) {
Toast.makeText(this, "num" + num, Toast.LENGTH_SHORT).show();
}
}
相信大家看到了EventBus的強大之處,EventBus有4種線程模式,POSTING,MAIN,BACKGROUND,ASYNC,默認線程是POSTING。
POSTING
默認情況下,EventBus使用的就是這個模式,說白了就是你在哪個線程發送事件,就在哪個線程接收事件。
MAIN
相信大家剛才也能看到,MAIN就是將接受事件放到主線程執行。
BACKGROUND
在后臺線程接收事件。如果不是在主線程提交,事件處理方法會直接在提交線程被調用。如果是在主線程提交,EventBus使用一個單獨的后臺線程按順序傳遞所有事件。事件處理使用這種模式應該能夠盡快返回避免阻塞后臺線程。
ASYNC
在一個單獨的線程接收事件。這個線程通常和提交的線程和主線程是獨立的。提交的事件從不等待事件處理方法。事件處理方法如果需要花費一段時間比如訪問網絡應該使用這種模式。避免在同一時間觸發大量長時間異步的處理方法來限制并發的線程。EventBus使用一個線程池來有效重復利用線程完成的異步事件處理程序的通知。
Stick Event
前面也說到了,EventBus可以取代intent在Activity或者Fragment中傳值,我們如果用前面那樣傳值肯定是不行的,應該怎么做呢?這時候就要用到EventBus另外一個功能了,Stick Event,那么接下來就給大家帶來Stick Event的使用。
package cn.lxt.stickeventbus;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStick = (Button) findViewById(R.id.btn_stick);
btnStick.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_stick:
//點擊按鈕,跳轉到StickActivity并攜帶參數,參數類型為String
EventBus.getDefault().postSticky("我是黏性事件");
StickActivity.start(this);
break;
}
}
}
package cn.lxt.stickeventbus;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
/**
* Created by Administrator on 2017/8/16 0016.
*/
public class StickActivity extends AppCompatActivity {
public static void start(Context context) {
context.startActivity(new Intent(context, StickActivity.class));
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stick);
//前面也說了,在任何你要接收事件的地方都要先注冊
EventBus.getDefault().register(this);
}
//同樣的,自定義一個方法,加上 @Subscribe,不同的是在后面再加上一句sticky = true告訴EventBus這是一個粘性事件
@Subscribe(sticky = true)
public void getEventBus(String str) {
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
//別忘了在onDestroy里面解綁
EventBus.getDefault().unregister(this);
}
}
接下來還是大家看一下效果圖
在進入StickActivity 之后,我們接收到了MainActivity發出的事件。
總結
EventBus的使用就說到這里,基本能滿足大家日常開發的需求了,文章中如果有任何錯誤歡迎指出,共同學習共同進步,當然如果有任何疑問,也歡迎留言。