簡體   English   中英

Android中的greenrobot EventBus發布活動

[英]greenrobot EventBus post event in Android

通過使用EventBus,我需要在Activity中發布一個事件(MyEvent)並在Android中的另一個Activity中接收該事件。 我嘗試了greenrobot EventBus性能測試項目,但無法做到這一點。

我在ActivitySubscriber中嘗試過

MyEvent event = new MyEvent();
EventBus.getDefault().post(event);

並嘗試在ActivityReceiver中接收事件

EventBus.getDefault().register(this);

public void onEvent(MyEvent event){
....
}

但是我無法收到這個活動。 任何人都可以讓我知道我在哪里做錯了嗎?

由於它們是兩個活動,因此ActivitySubscriber在仍未創建ActivityReceiver或處於停止模式( onStop() )時發布事件。 你需要使用粘性事件,即

  • ActivitySubscriber.postSticky(...)

對於ActivityReceiver,您有兩種選擇:

  • EventBus.getDefault().register(this)以及EventBus.getDefault().getStickyEvent()之后的某個地方EventBus.getDefault().getStickyEvent()
  • EventBus.getDefault().registerSticky()然后使用常規EventBus.getDefault().onEvent(...)

更新: EventBus 3.0改變了訂閱方式。

不需要最終具有特定后綴的方法名稱,而是注釋。

如何使用版本3:

//// in your build.gradle
compile 'de.greenrobot:eventbus:3.0.0-beta1'
// alternatively you can target latest whatever currently
// compile 'de.greenrobot:eventbus:+'

//// from a class which needs to dispatch an event
// posting an event is as before, no changes
// here we dispatch a sticky event
EventBus.getDefault().postSticky(myStickyEvent);

//// from your class which needs to listen
// method name can be any name
// any of subscribe params is optional, i.e. can use just @Subscribe
@Subscribe(threadMode = ThreadMode.MainThread, sticky = true, priority = 1)
public void onEventBusEvent(@Nullable final StickyEvent stickyEvent) {
    if (stickyEvent != null) {
      ...
      // optionally you can clean your sticky event in different ways
      EventBus.getDefault().removeAllStickyEvents();
      // EventBus.getDefault().removeStickyEvent(stickyEvent);
      // EventBus.getDefault().removeStickyEvent(StickyEvent.class);
    }
}

有關版本3的更多詳細信息和比較:

從消息來源中提取的一些細節:

  • ThreadMode.PostThread

    訂閱者將在同一個帖子中調用,該帖子將發布該事件。 這是默認值。 事件傳遞意味着開銷最小,因為它完全避免了線程切換。 因此,對於已知完成的簡單任務,這是一個推薦的模式,非常短的時間而不需要主線程。 使用此模式的事件處理程序必須快速返回以避免阻止發布線程,這可能是主線程。

  • ThreadMode.MainThread

    訂閱者將在Android的主線程(有時稱為UI線程)中調用。 如果發布線程是主線程,則將直接調用事件處理程序方法。 使用此模式的事件處理程序必須快速返回以避免阻塞主線程。

  • ThreadMode.BackgroundThread

    訂閱者將在后台線程中調用。 如果發布線程不是主線程,則將在發布線程中直接調用事件處理程序方法。 如果發布線程是主線程,則EventBus使用單個后台線程,該線程將按順序傳遞其所有事件。 使用此模式的事件處理程序應嘗試快速返回以避免阻止后台線程。

  • ThreadMode.Async

    事件處理程序方法在單獨的線程中調用。 這始終獨立於發布線程和主線程。 發布事件永遠不會等待使用此模式的事件處理程序方法。 如果事件處理程序的執行可能需要一些時間,例如用於網絡訪問,則應使用此模式。 避免同時觸發大量長時間運行的異步處理程序方法來限制並發線程數。 EventBus使用線程池從已完成的異步事件處理程序通知中有效地重用線程。

  • @Subscribe 默認
    • threadMode = ThreadMode.PostThread
    • sticky = false - 如果為true,則傳遞最近的粘性事件(使用de.greenrobot.event.EventBus.postSticky(Object)給此訂閱者(如果可用事件)
    • priority = 0 - 訂閱者優先級以影響事件傳遞的順序。 在同一個傳遞線程中,較高優先級的訂戶將在優先級較低的其他訂戶之前接收事件。 默認優先級為0。注:優先級影響使用不同的線程模式下用戶之間傳遞的順序。

編輯2

現在有一個專門的網站可以為lib的創建者提供任何Greenrobot EventBus問題:

http://greenrobot.org/eventbus/

dependencies { .. compile 'org.greenrobot:eventbus:3.0.0' .. }

進入Modules Build gradle的依賴項部分

  1. 創建一個MessageEvent類

 public final class MessageEvent { private MessageEvent() { throw new UnsupportedOperationException("This class is non-instantiable"); } public static class Message1{ public String str1; public Message1(String str) { str1 = str; } } public static class Message2{ public String str2; public Message2(final String str) { str2 = str; } } } // so on 

  1. 假設我們有Fragment1,並且有一個按鈕,假設要向MainActivity發送消息

 public class Fragment1 extends Fragment { private View frView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { frView = inflater.inflate(R.layout.fragment1, container, false); btn = (Button) frView.findViewById(R.id.button); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { frView.setBackgroundColor(Color.RED); EventBus.getDefault().post(new MessageEvent.Message1("1st message")); EventBus.getDefault().post(new MessageEvent.Message2("2nd message")); } }); return frView; } 

  1. 最后結束MainActivity監聽並采取行動

 public class MainActivity extends AppCompatActivity { @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override protected void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment1 Fragment1 = new Fragment1(); getFragmentManager().beginTransaction().replace( R.id.activity_main, Fragment1, "Fragment 1").commit(); } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage1(MessageEvent.Message1 event) { Toast.makeText(getApplication(), event.str1, Toast.LENGTH_LONG).show(); } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage2(MessageEvent.Message2 event) { Toast.makeText(getApplication(), event.str2, Toast.LENGTH_LONG).show(); } } 

在ActivityReceiver類里面,替換

EventBus.getDefault().register(this); 

EventBus.getDefault().register(this, MyEvent.class);

這實際上取決於此代碼存在的時間和位置。 請記住,您必須先注冊事件才能收到它們,並且注冊在運行時進行,而不是在編譯時進行。

因此,您必須確保注冊第二個活動發布活動。 我只想在以下行中放置一些斷點並確保調試器在此處停止:

EventBus.getDefault().register(this); 

在你到達這里之前:

EventBus.getDefault().post(event);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM