知乎专栏 |
EventBus 有五种线程模型(ThreadMode)
Posting:直接在事件发布者所在线程执行事件处理方法; Main:直接在主线程中执行事件处理方法(即UI线程),如果发布事件的线程也是主线程,那么事件处理方法会直接被调用,并且未避免ANR,该方法应避免进行耗时操作; MainOrdered:也是直接在主线程中执行事件处理方法,但与Main方式不同的是,不论发布者所在线程是不是主线程,发布的事件都会进入队列按事件串行顺序依次执行; BACKGROUND:事件处理方法将在后台线程中被调用。如果发布事件的线程不是主线程,那么事件处理方法将直接在该线程中被调用。如果发布事件的线程是主线程,那么将使用一个单独的后台线程,该线程将按顺序发送所有的事件。 Async:不管发布者的线程是不是主线程,都会开启一个新的线程来执行事件处理方法。如果事件处理方法的执行需要一些时间,例如网络访问,那么就应该使用该模式。为避免触发大量的长时间运行的事件处理方法,EventBus使用了一个线程池来有效地重用已经完成调用订阅者方法的线程以限制并发线程的数量。 后面会通过代码展示五种ThreadMode的工作方式。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ThreadModeActivity"> <Button android:id="@+id/buttonSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:text="Send" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/buttonThread" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:text="Send Thread" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/buttonSend" /> </android.support.constraint.ConstraintLayout>
package cn.netkiller.eventbus; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; public class ThreadModeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thread_mode); EventBus.getDefault().register(this); findViewById(R.id.buttonSend).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("EventBus Thread : ", Thread.currentThread().getName()); EventBus.getDefault().post("http://www.netkiller.cn"); } }); findViewById(R.id.buttonThread).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { Log.d("EventBus Thread : ", Thread.currentThread().getName()); EventBus.getDefault().post("http://www.netkiller.cn"); } }).start(); } }); } @Subscribe(threadMode = ThreadMode.POSTING) public void onMessageEventPostThread(String event) { Log.d("EventBus PostThread", "Message: " + event + " thread: " + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEventMainThread(String event) { Log.d("EventBus MainThread", "Message: " + event + " thread: " + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.MAIN_ORDERED) public void onEventMainOrdered(String event) { Log.d("EventBus MainOrdered", "Message: " + event + " thread:" + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.BACKGROUND) public void onMessageEventBackgroundThread(String event) { Log.d("EventBus BackgroundThread", "Message: " + event + " thread: " + Thread.currentThread().getName()); } @Subscribe(threadMode = ThreadMode.ASYNC) public void onMessageEventAsync(String event) { Log.d("EventBus Async", "Message: " + event + " thread: " + Thread.currentThread().getName()); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
在 main 线程中发布消息
D/EventBus Thread :: main D/EventBus MainThread: Message: http://www.netkiller.cn thread: main D/EventBus PostThread: Message: http://www.netkiller.cn thread: main D/EventBus Async: Message: http://www.netkiller.cn thread: pool-1-thread-1 D/EventBus BackgroundThread: Message: http://www.netkiller.cn thread: pool-1-thread-2 D/EventBus MainOrdered: Message: http://www.netkiller.cn thread:main
在线程中发布消息
D/EventBus Thread :: Thread-2 D/EventBus BackgroundThread: Message: http://www.netkiller.cn thread: Thread-2 D/EventBus PostThread: Message: http://www.netkiller.cn thread: Thread-2 D/EventBus Async: Message: http://www.netkiller.cn thread: pool-1-thread-2 D/EventBus MainOrdered: Message: http://www.netkiller.cn thread:main D/EventBus MainThread: Message: http://www.netkiller.cn thread: main