Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

50.4. 綫程模型

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