7

EventBus を使用して、Android の Activity にイベント (MyEvent) を投稿し、別の Activity でイベントを受信する必要があります。greenrobot EventBus パフォーマンス テスト プロジェクトを試しましたが、その方法がわかりませんでした。

ActivitySubscriberでやってみた

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

ActivityReceiverでイベントを次のように受信しようとしました

EventBus.getDefault().register(this);

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

しかし、私はイベントを受け取ることができません。誰が私がどこで間違っているのか教えてもらえますか?

4

4 に答える 4

24

これらは 2 つのアクティビティであるため、まだ作成されていない、または失速モード ( )ActivitySubscriberのときにイベントを投稿します。スティッキー イベントを使用する必要があります。ActivityReceiveronStop()

  • ActivitySubscriber.postSticky(...)

また、ActivityReceiver には次の 2 つのオプションがあります。

  • EventBus.getDefault().register(this)そしてその後のどこか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/

于 2013-02-04T06:18:44.920 に答える
3
  1. 追加

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();
    }
}

于 2016-11-25T23:56:09.663 に答える
0

このコードがいつ、どこに存在するかによって異なります。イベントを受け取る前に登録する必要があり、登録はコンパイル時ではなく実行時に行われることに注意してください。

そのため、2 番目のアクティビティを登録した後で、イベントを投稿していることを確認する必要があります。次の行にいくつかのブレークポイントを配置し、デバッガーがここで停止するようにします。

EventBus.getDefault().register(this); 

ここにたどり着く前に:

EventBus.getDefault().post(event);
于 2016-02-26T11:47:00.023 に答える