- 直接git clone下來:git clone https://github.com/greenrobot/EventBus.git
- 到github網(wǎng)站下載乳愉。https://github.com/greenrobot/EventBus這兩種方式都要手動將jar包放進工程的libs目錄下,然后添加依賴
- 在androidstudio的工程目錄下的build.gradle中添加代碼:compile 'org.greenrobot:eventbus:3.0.0'會自動下載到工程的External Libraries下(這句代碼是在dependencies節(jié)點下的)
- 我下載好了捕虽,點擊去下載http://download.csdn.net/detail/chenyannan0617/9509229
簡單介紹:
在應用中當想通知其他組件某些事情發(fā)生時就會使用到開源框架EventBus薯鳍。它主要功能是可以替代Intent、Handler崩溪、BroadCast在Fragment斩松、Activity、Service乳幸、線程之間傳遞消息钧椰。優(yōu)點是開銷小,代碼簡潔瓶埋,解耦代碼诊沪。
貼一張官方的圖:
我認為圖就描述了一件事,發(fā)布者publisher通過post方法發(fā)事件晕粪,訂閱者subscriber通過onEvent方法拿到
關鍵方法:
- EventBus.getDefault().register(this);//訂閱事件
- EventBus.getDefault().post(object);//發(fā)布事件
- EventBus.getDefault().unregister(this);//取消訂閱
在事件接收方就會有四種形式(就是四種線程模式):
- ThreadMode.POSTING:如果訂閱者在使用事件處理函數(shù)時候指定了這種線程模式巫湘,那么該事件是在哪個線程發(fā)布出來的橄仆,那么處理函數(shù)就會在這個線程中執(zhí)行,也就是說發(fā)布事件和接收事件是在同一個線程怠褐。在這種線程模式下盡量避免做耗時操作您宪,因為會阻塞事件的傳遞奠涌,很有可能引起ANR
- ThreadMode.ASYNC:這種線程模式就是說磷杏,無論事件在哪個線程發(fā)布极祸,該事件的處理函數(shù)都會在新建的子線程中執(zhí)行,此事件處理函數(shù)中是不能進行UI操作的
- ThreadMode.BACKGROUND:這種線程模式意思是遥金,如果事件是在UI線程中發(fā)布出來的稿械,那么該事件處理函數(shù)就會在子線程中執(zhí)行;如果事件是在子線程中發(fā)布的页眯,那就還在這個線程中處理厢呵。在這種模式下是不能更新UI操作的
- ThreadMode.MAIN:如果線程模式是MAIN,那么無論事件是在什么線程發(fā)送出來的忿族,該事件處理函數(shù)都會在UI線程中執(zhí)行蝌矛,可以用來更新UI错英,但是注意不要做耗時操作椭岩。
舉例上代碼:
簡單一點的如:有兩個界面,ActivityA和ActivityB判哥,從ActivityA界面跳轉(zhuǎn)到ActivityB界面后塌计,ActivityB要給ActivityA發(fā)送一個消息,ActivityA收到消息后在界面上顯示出來
實現(xiàn)方式:A中注冊章钾,接收訂閱的事件,取消注冊惨撇;B中post事件府寒;先看下效果
代碼:A activity
public class MainActivity extends Activity {
Button btn;
private TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注冊EventBus
EventBus.getDefault().register(this);
mText = (TextView) findViewById(R.id.text);
btn = (Button) findViewById(R.id.btn_try);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);
}
});
}
//接收訂閱的事件
@Subscribe(threadMode = ThreadMode.POSTING)
public void getdate(String event) {
mText.setText(event);
}
//取消注冊
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
B activity
public class SecondActivity extends Activity {
private Button btn_FirstEvent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
btn_FirstEvent = (Button) findViewById(R.id.btn_first_event);
btn_FirstEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 發(fā)送事件
EventBus.getDefault().post("第二個界面纺棺,發(fā)送回來的POSITING");
Toast.makeText(getApplicationContext(), "已經(jīng)發(fā)送回去", Toast.LENGTH_SHORT).show();
}
});
}
}
另一種屬性用法:EventBus還能收到未注冊時發(fā)送的最后一個事件邪狞;沒有注冊就發(fā)送事件,如發(fā)送三次后注冊巨朦,那么現(xiàn)在就能獲取到最后一次發(fā)送的事件剑令。起作用的就一句代碼,sticky = true 棚蓄;注意碍脏,發(fā)送事件時候不是post了而是postSticky;如果不加這句代碼是沒有這種效果的役拴。還是先看看圖吧
貼代碼:
主Activity
public class MainActivity extends Activity {
int index = 1;
int count = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sticky_mode);
findViewById(R.id.post).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "發(fā)送弟"+count++ +"次", Toast.LENGTH_SHORT).show();
EventBus.getDefault().postSticky(new MessageEvent("發(fā)送事件弟:" + index++ +"次"));
}
});
findViewById(R.id.regist).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().register(MainActivity.this);
}
});
findViewById(R.id.unregist).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().unregister(MainActivity.this);
}
});
}
@Subscribe(threadMode = ThreadMode.POSTING, sticky = true)
public void postThread(MessageEvent messageEvent) {
Log.e("PostThread", messageEvent.getMessage()+Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void mainThread(MessageEvent messageEvent) {
Log.e("MainThread", messageEvent.getMessage()+Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true)
public void backgroundThread(MessageEvent messageEvent) {
Log.e("BackgroundThread", messageEvent.getMessage()+Thread.currentThread().getName());
}
@Subscribe(threadMode = ThreadMode.ASYNC, sticky = true)
public void async(MessageEvent messageEvent) {
Log.e("Async", messageEvent.getMessage()+Thread.currentThread().getName());
}
}
xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發(fā)送事件"/>
<Button
android:id="@+id/regist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注冊"/>
<Button
android:id="@+id/unregist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消注冊"/>
</LinearLayout>
MessageEvent類
public class MessageEvent {
private String message;
public MessageEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
從圖中和代碼中也可以看出褥紫,四種線程模式的規(guī)律。從什么線程發(fā)送事件部念,到什么線程中獲得事件。
第二個示例中事件都是從主線程中發(fā)送出來的印机,接收的線程模式是Main和post的就也在主線程中接收射赛,另外兩種模式下就是在子線程中接收了。
歡迎進群討論楣责,QQ群:104286694