A detailed description of the differences between android development EventBus 3.0

Keywords: Android github

1. Download EventBus's Class Library
Source code: https://github.com/greenrobot/EventBus
Dependencies can be added directly:

compile 'org.greenrobot:eventbus:3.0.0'

If you've read the previous article, you should have used EventBus in a simple way. In the previous section, we used the onEventMainThread method.There are actually other ways before 3.0

  • onEvent:
If you use onEvent as a subscription function, in which thread the event was published, onEvent runs in that thread, that is, the publishing and receiving event threads are on the same thread.With this method, time-consuming operations cannot be performed in the onEvent method, which can easily delay event distribution.
  • onEventMainThread:
If you use onEventMainThread as a subscription function, the onEventMainThread executes in the UI thread regardless of which thread the event is published, and the receive event runs in the UI thread. This is useful in Android because only the UI thread can follow the new UI in Android, so time-consuming operations cannot be performed in the onEvnetMainThread method..
  • onEventBackground:
If onEventBackgroundis used as a subscription function, then if the event is published in the UI thread, onEventBackgroundruns in the child thread, and if the event is originally published in the child thread, the onEventBackgroundfunction runs directly in the child thread.
  • onEventAsync:
Using this function as a subscription function, a new child thread will be created to execute onEventAsync regardless of which thread the event is published on.

The steps in the previous article are not detailed.

1. Custom Events

public class DemoEvent {

    private String msg;
    public DemoEvent(String msg){
        this.msg=msg;
    }

    public String getMsg(){
        return msg;
    }

}

2. Subscribers (MainActivity here)

public class MainActivity extends AppCompatActivity {

    private Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.button);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Subscribe
    public void onEventMainThread(DemoEvent event) {
        Log.e("onEventMainThread", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe
    public void onEvent(DemoEvent event) {
        Log.e("onEvent", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe
    public void onEventBackground(DemoEvent event) {
        Log.e("onEventBackground", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe
    public void onEventAsync(DemoEvent event) {

        Log.e("onEventAsync", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

When a message is received, print out the received message and the name of the current thread

3. Send a message

public class SecondActivity extends AppCompatActivity {

    private Button bt_MainThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        bt_MainThread = (Button) findViewById(R.id.button1);
        bt_MainThread.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                EventBus.getDefault().post(new DemoEvent("postThread---"+Thread.currentThread().getName()));
            }
        });
    }
}

Message sent is the thread name of postThread

Run Results

Looking at the log found a problem. The thread on which the message was sent is mainthread, but the onEventBackground method and onEventAsync method are not running in the child thread

Message handling after EventBus 3.0

Many methods used to be difficult to remember and use, but now we only need one method. Here we need to borrow a ThreadMode.
You can Click on the link to view the official introduction

  • POSTING (default)
If an event handler is used to specify the thread model as POSTING, then in which thread the event was published, the event handler runs in that thread, that is, the publishing and receiving events are on the same thread.Avoid time-consuming operations in event handlers where the threading model is POSTING, as it can block the delivery of events and possibly even cause ANR s.
  • MAIN:
 Processing of events is performed in the UI thread.Event processing time cannot be too long, it will be ANR long.
  • BACKGROUND:
If an event is published in a UI thread, the event handler runs in a new thread, and if the event was originally published in a child thread, the event handler executes directly in the thread that published the event.UI update operations are prohibited in this event handler.
  • ASYNC:
The event handler executes in a new child thread regardless of which thread the event is published, and similarly, UI updates are prohibited in this event handler.

With previous understanding, these four patterns correspond to those four methods, and don't remember method names anymore

  • Event handling at this time
@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
    ...
}

Method names can be arbitrarily named, and patterns can be chosen based on different situations
Next, modify MainActivity's method of receiving messages

public class MainActivity extends AppCompatActivity {

    private Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.button);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }


    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessagePOSTING(DemoEvent event) {
        Log.e("ThreadMode.POSTING", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageMAIN(DemoEvent event) {
        Log.e("ThreadMode.MAIN", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageBACKGROUND(DemoEvent event) {
        Log.e("ThreadMode.BACKGROUND", event.getMsg() + "----" + Thread.currentThread().getName());
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageASYNC(DemoEvent event) {
        Log.e("ThreadMode.ASYNC", event.getMsg() + "----" + Thread.currentThread().getName());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}

The method name does not matter. The thread that determines the method execution is Mode.
Result

You can see ThreadMode.ASYNC and ThreadMode.BACKGROUND, whose methods are executed in child threads, respectively.Evetbus also uses thread pool threads to efficiently reuse child threads from events.

Finally, who can tell me why subthreads were not opened before 3.0?

Posted by WLW on Thu, 27 Jun 2019 12:32:19 -0700