一、EventBus3.0的基本簡介:
以前Android組件之間都是用Intent或者Broadcast來進行通信的。而EventBus則大大簡化了應用程序內各組件間、組件與後臺線程間的通信
ThreadMode:這是個枚舉,有四個值,決定訂閱函數在哪個線程執行
PostThread:事件發送者在哪個線程就執行在哪個線程。默認值就是這個
MainThread:訂閱函數一定執行在主線程。同onEventMainThread方法
BackgroundThread:如果是事件從子線程發出,訂閱函數就執行在那個子線程,不會創建新的子線程;如果主線程發出事件,則創建子線程。同onEventBackgroundThread方法
Async:一定創建子線程。同onEventAsync方法。
sticky:默認爲false,如果爲true,當通過postSticky發送一個事件時,這個類型的事件的最後一次事件會被緩存起來,當有訂閱者註冊時,會把之前緩存起來的這個事件直接發送給它。使用在比如事件發送者先啓動了,訂閱者還沒啓動的情況。
priority:默認值爲0。訂閱了同一個事件的訂閱函數,在ThreadMode值相同的前提下,收到事件的優先級。
二、實戰操作
當然首先要進行環境配置:
在build.gradle配置如下
project下的:
buildscript {
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
app下的:
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
compile 'org.greenrobot:eventbus:3.0.0'
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}
//這個是優化編譯速度的,可選項
apt {
arguments {
eventBusIndex "com.whoislcj.eventbus.MyEventBusIndex"
}
}
先來看一下效果圖
post發送
postSticky發送
從效果圖中可以看出,使用post發送事件,除了自身能收到信息外,SecondActivity收不到MainActivity發送的信息。這是因爲post的時候SecondActivity還沒註冊事件,自然收不到任何信息。使用postSticky發送事件,MainActivity和SecondActivity都能收到發送的信息。
綜上,可以看出post和postSticky的區別就是post就是直接發送事件,前提是你要在post之前,就已經註冊了事件的。而postSticky則在發送的時候就已經緩存了事件,直到有註冊sticky的事件發生時,他就會觸發。不明白的話,再仔細看看代碼。
注意:註冊的時候要儘量在onCreate或者onStart方法上註冊,取消註冊則在onDestroy上。
代碼示例:
public class MainActivity extends AppCompatActivity {
TextView mTextView;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView= (TextView) findViewById(R.id.tv);
EventBus.getDefault().register(this);
}
public void post(View view){
EventBus.getDefault().post("在MainActivity使用post(直接發佈)");
}
public void postSticky(View view){
EventBus.getDefault().postSticky("在MainActivity使用postSticky(滯留髮布)");
}
public void second(View view){
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(String msg){
mTextView.setText(msg);
}
@Override protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
public class SecondActivity extends AppCompatActivity {
private TextView mTextView;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTextView = (TextView) findViewById(R.id.show);
EventBus.getDefault().register(this);
}
public void post(View view) {
EventBus.getDefault().post("在SecondActivity使用post(直接發佈)");
}
public void postSticky(View view) {
EventBus.getDefault().postSticky("在SecondActivity使用postSticky(滯留髮布)");
}
public void back(View view) {
Intent intent = new Intent(SecondActivity.this,MainActivity.class);
startActivity(intent);
}
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onEvent(String msg){
mTextView.setText(msg);
}
@Override protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
三、總結
爲確保在SecondActivity中能收到消息。MainActivity和SecondActivity開啓模式爲 singleTask或者,singleInstancce,確保回去看到mainActivity爲同一個實例。才能接收到消息。(其他人的demo回傳消息的時候是通過finish把本身activity殺死了,直接回到了前面的MainActivity,還是保證是同一示例對象~~~)
我展示了在MainActivity上的操作,至於在SecondActivity上的操作也是一樣的,自己去試試,有不足或有疑問的評論下方留言。
在實際項目的使用中,register和unregister通常與Activity和Fragment的生命週期相關,ThreadMode.MainThread可以很好地解決Android的界面刷新必須在UI線程的問題,不需要再回調後用Handler中轉(EventBus中已經自動用Handler做了處理),黏性事件可以很好地解決post與register同時執行時的異步問題,事件的傳遞也沒有序列化與反序列化的性能消耗,足以滿足我們大部分情況下的模塊間通信需求。
這篇只是知其然,卻不知其所以然,要想知其所以然就得深入源碼去了解了。