0%

EventBus 的应用

EventBus 是 GreenRobot 开发的 Android 和 Java 的开源库,使用发布者 / 订阅者模式进行解耦合。EventBus 使组件之间的通信只需几行代码即可搞定,极度解耦并且简化了代码,消除依赖关系并加快应用程序开发。这里是 EventBus 的官网:https://greenrobot.org/eventbus/。在介绍 EventBus 的通信方法之前,首先会介绍常规的通信方法,比如说设置监听或者是使用广播等方式,以此来说明常规的方法都有其弊端,然后使用 EventBus 来完成组件之间的通信,通过案例体会 EventBus 在组件通信过程中的优势。

GreenRobot 组织开发的这款开源库,从这个项目的名称就充分体现了它的功能,EventBus 有两个单词组成 ——Event 和 Bus。那什么是 Event 呢?在 Android 平台上有非常多的事件类型,其中最常见的就是触控事件,当触控事件发生的时候,应用程序需要做出一些响应,从而来和用户进行交互。应用程序的各个组件之间以及应用程序和用户之间都需要进行通信。有了消息通信,应用程序才是可交互的。那接下来的问题就是如何进行通信呢?也就是说如何去发送和处理消息呢?

在回答这个问题之前,我们先来看一下什么叫做 Bus。现在请调整思维,脱离软件开发领域,进入到日常生活场景。我们经常需要从一个地方到达另外一个地方,比如说出发地是上海。目的地是杭州。一开始我们位于出发地,如果靠自己的双脚走路。你知道路线就是一个不小的挑战。通常情况下,我们会借助公共交通系统,有了这样的运输系统,我们就只需要做两件事儿:第一件事儿就是从出发地上车;第二件事儿就是在目的地下车。整个运输过程当中,这个交通系统对我们来说是不可见的,我们并不需要了解其内部细节。只需要做两件事儿,第一件就是从出发地上车,第二件就是在目的地下车。

那现在我们回到软件开发领域,这次我们需要运输的对象不再是自己。而是事件消息,这个事件有一个发送方,具体来说它就会是某一个 Java 类当中的某一个方法,我们是在这个方法中来发送消息。那还有一个订阅方,订阅方就是表示我对这个事件感兴趣。我要接收这个事件消息,我要处理这个事件消息,借助 EventBus 这个运输系统。我们需要做两件事儿,第一件事儿就是在这个发送方去发布消息,然后 EventBus 的运输系统就会来负责在内部来传递这个消息。对于我们需要关注的第二件事儿,就是在订阅方来以订阅和处理这个事件。整个过程当中 EventBus 就是一个黑盒子,我们只需要做两件事儿。第一件事儿就是发布事件,第二件事儿就是订阅和处理事件。这次应该 EventBus 已经有了一个初步的认识,它就是一个能够帮助我们完成组件间通信的工具。需要掌握如何使用 EventBus 完成事件的订阅和发布,从而借助这样的一个开源库轻松的实现组件间的相互通信。

常规通信方法

在介绍这些方式之前,先介绍一下项目 Demo 的功能,

Listener 监听的方式


MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ImageView ivEmoji;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
ivEmoji = findViewById (R.id.iv_emoji);
}

public void showDialogFragment(View view) {
// Display DialogFragment
PublisherDialogFragment fragment = new PublisherDialogFragment();
fragment.show (getSupportFragmentManager (), "publisher");
fragment.setEventListener (new PublisherDialogFragment.OnEventListener () {
@Override
public void onSuccess() {
ivEmoji.setImageResource (R.drawable.ic_happy);
}

@Override
public void onFailed() {
ivEmoji.setImageResource (R.drawable.ic_bad);
}
});
}
}

activity_main.xml 布局文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<ImageView
android:id="@+id/iv_emoji"
android:layout_centerInParent="true"
android:layout_width="200dp"
android:layout_height="200dp"/>

<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="20dp"
android:layout_marginEnd="20dp"
android:onClick="showDialogFragment"
android:background="@drawable/ic_add"
/>

</RelativeLayout>

PublisherDialogFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class PublisherDialogFragment extends DialogFragment {
private static final String TAG = "PublisherDialogFragment";

private OnEventListener onEventListener;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder (getActivity ());
builder.setTitle ("Publisher");
String [] items = new String[]{"Success", "Failed"};
builder.setItems (items, (dialog, which) -> {
switch (which){
case 0: // Success
onEventListener.onSuccess ();
break;
case 1: // Failed
onEventListener.onFailed ();
break;
default:
break;
}
});
return builder.create ();
}

public interface OnEventListener{
void onSuccess();
void onFailed();
}

public void setEventListener(OnEventListener listener){
this.onEventListener = listener;
}
}

这样做虽然实现了功能,但是耦合性还是比较高的,对于事件的发布方必须定义接口,而且当时间越来越多的时候我们就需要定义越来越多的接口和方法,这样事件的接收方和发送方耦合在了一起,当两个组件中存在依赖的时候,耦合关系就建立了,其中一个修改的话就会影响到另外一个组件,耦合度过高是不利于软件开发的,所以还有什么其他的通信方式呢?接下来看看本地广播这种形式。

本地广播的方式

为什么使用本地广播呢?因为只是在这个应用内部进行通信,其他 App 不需要监听这个广播,所以采用本地广播即可:

MainActivity 中注册广播监听,注意在 Activity 销毁时取消广播监听,MainActivity.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
......
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ImageView ivEmoji;

public static final String HAND_EVENT_ACTION = "hand_event_action";;
public static final String result = "result";
private LocalBroadcastManager broadcastManager;

BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction ().equals (HAND_EVENT_ACTION)){
if(intent.getBooleanExtra (result, false)){
ivEmoji.setImageResource (R.drawable.ic_happy);
}else {
ivEmoji.setImageResource (R.drawable.ic_bad);
}
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
ivEmoji = findViewById (R.id.iv_emoji);
broadcastManager = LocalBroadcastManager.getInstance (this);
}

@Override
protected void onStart() {
super.onStart ();

IntentFilter filter = new IntentFilter(HAND_EVENT_ACTION);
broadcastManager.registerReceiver (receiver, filter);
}

@Override
protected void onStop() {
super.onStop ();
broadcastManager.unregisterReceiver (receiver);
}

public void showDialogFragment(View view) {
// Display DialogFragment
PublisherDialogFragment fragment = new PublisherDialogFragment();
fragment.show (getSupportFragmentManager (), "publisher");
}
}

PublisherDialogFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
......
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

public class PublisherDialogFragment extends DialogFragment {
private static final String TAG = "PublisherDialogFragment";

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder (getActivity ());
builder.setTitle ("Publisher");
String [] items = new String[]{"Success", "Failed"};
builder.setItems (items, (dialog, which) -> {
Intent intent = new Intent(MainActivity.HAND_EVENT_ACTION);
switch (which){
case 0: // Success
intent.putExtra (MainActivity.result, true);
LocalBroadcastManager.getInstance (getActivity ())
.sendBroadcast (intent);
break;
case 1: // Failed
intent.putExtra (MainActivity.result, false);
LocalBroadcastManager.getInstance (getActivity ())
.sendBroadcast (intent);
break;
default:
break;
}
});
return builder.create ();
}
}

对于广播通信的方式对于发送方需要创建 Intent,并且双方必须规定好 Intent 的 Action,而且必须规定好 Intent 中的数据字段。对于消息的接收方,又需要解析 Intent 中的数据,可以说还是比较麻烦了。而且广播都是运行在 UI 线程,如果想要在后台线程需要我们手动作切换,使用起来就不是很方便了。

使用 EventBus 通信

下面来直接使用 EventBus 进行组件之间的通信,也就是上面的例子,看看可以省略多少代码呢?

使用 EventBus 重点需要三步:定义事件 -> 在订阅方进行订阅 -> 发布方发布事件,首先需要引入依赖:

1
implementation group: 'org.greenrobot', name: 'eventbus', version: '3.1.1'

定义一个事件,其实就是一个普通的 Java 类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyEvent {
private boolean result;

public MyEvent(boolean result) {
this.result = result;
}

public boolean isResult() {
return result;
}

public void setResult(boolean result) {
this.result = result;
}
}

MainActivity.java 中订阅事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

public class MainActivity extends AppCompatActivity {
private ImageView ivEmoji;

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

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

@Subscribe
public void onEvent(MyEvent myEvent){
if(myEvent.isResult ()){
ivEmoji.setImageResource (R.drawable.ic_happy);
}else {
ivEmoji.setImageResource (R.drawable.ic_bad);
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
ivEmoji = findViewById (R.id.iv_emoji);
}

public void showDialogFragment(View view) {
// Display DialogFragment
PublisherDialogFragment fragment = new PublisherDialogFragment();
fragment.show (getSupportFragmentManager (), "publisher");
}
}

PublisherDialogFragment.java 作为发布方发布事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class PublisherDialogFragment extends DialogFragment {

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder (getActivity ());
builder.setTitle ("Publisher");
String [] items = new String[]{"Success", "Failed"};
builder.setItems (items, (dialog, which) -> {
switch (which){
case 0: // Success
EventBus.getDefault ().post (new MyEvent(true));
break;
case 1: // Failed
EventBus.getDefault ().post (new MyEvent(false));
break;
default:
break;
}
});
return builder.create ();
}
}

EventBus 线程模式

EventBus3.0 有四种线程模型,分别是:
1、POSTING:默认模式,表示事件处理函数的线程跟发布事件的线程在同一个线程。
2、MAIN:表示事件处理函数的线程在主线程 (UI) 线程,因此在这里不能进行耗时操作。
3、BACKGROUND:表示事件处理函数的线程在后台线程,因此不能进行 UI 操作。如果发布事件的线程是主线程 (UI 线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
4、ASYNC:表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行 UI 操作。

POSTING 模式

POSTING 模式是 EventBus 默认的模式,我们在使用的时候不需要再订阅者的方法的注解后面添加模式选项,但是这种只能在同一个线程中接收,也就是说,如果是在主线程中发布消息就只能在主线程中接收消息,如果是在子线程中,那么也只能在相同的子线程中去接收消息,在下面的例子中,演示的是 50% 的随机几率在新线程发送事件,50% 的随机几率在 UI 线程发送事件。

订阅者代码:(MainActivity.java)

1
2
3
4
5
6
7
8
9
// POSTING 模式 
@Subscribe (threadMode = ThreadMode.POSTING)
public void onPostingEvent(final PostingEvent event){
String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

发布者代码:(PublisherDialogFragment.java)
1
2
3
4
5
6
7
8
9
10
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new PostingEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new PostingEvent(Thread.currentThread ().toString ()));
}

MAIN 模式

MAIN 模式保证了订阅者指定的那个接收方法肯定要主线程中执行,可以放心的在里面执行更新 UI 操作。无论发布者是在主线程中还是在那一条子线程中发布消息,这边接收的都在主线程中。

订阅者代码:(MainActivity.java)

1
2
3
4
5
6
7
8
9
// MAIN 模式 
@Subscribe (threadMode = ThreadMode.MAIN)
public void onMainEvent(final MainEvent event){
String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

发布者代码:(PublisherDialogFragment.java)
1
2
3
4
5
6
7
8
9
10
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new MainEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new MainEvent(Thread.currentThread ().toString ()));
}

MAIN_ORDER 模式

MAIN_ORDER 模式与 MAIN 模式类似,但是稍微有点区别:MAIN_ORDER 模式和 MAIN 一样都是在主线程中,不同的就是不需要等带订阅方完成订阅,发布方就可以继续自己的代码运行:

订阅者代码:(MainActivity.java)

1
2
3
4
5
6
7
8
9
10
11
12
13
// MAIN_ORDER 模式 
@Subscribe (threadMode = ThreadMode.MAIN_ORDERED)
public void onMainOrderEvent(final MainOrderEvent event){
Log.i (TAG, "onMainOrderEvent: enter @" + SystemClock.uptimeMillis ());
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (Thread.currentThread ().toString ());
try {
TimeUnit.SECONDS.sleep (1);
} catch (InterruptedException e) {
e.printStackTrace ();
}
Log.i (TAG, "onMainOrderEvent: exit @" + SystemClock.uptimeMillis ());
}

发布者代码:(PublisherDialogFragment.java)
1
2
3
Log.i (TAG, "onCreateDialog: before @" + SystemClock.uptimeMillis ());
EventBus.getDefault ().post (new MainOrderEvent(Thread.currentThread ().toString ()));
Log.i (TAG, "onCreateDialog: after @" + SystemClock.uptimeMillis ());

同样的代码当使用 MAIN 模式时:(即 @Subscribe (threadMode = ThreadMode.MAIN)):

同样的代码当使用 MAIN_ORDER 模式时:(即 @Subscribe (threadMode = ThreadMode.MAIN_ORDER)):

BACKGROUND


订阅者代码:(MainActivity.java)

1
2
3
4
5
6
7
8
9
// BACKGROUND 模式 
@Subscribe (threadMode = ThreadMode.BACKGROUND)
public void onBackgroundEvent(final MainOrderEvent event){
final String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

发布者代码:(PublisherDialogFragment.java)
1
2
3
4
5
6
7
8
9
10
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new BackgroundEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new BackgroundEvent(Thread.currentThread ().toString ()));
}

ASYNC

表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行 UI 操作:

订阅者代码:(MainActivity.java)

1
2
3
4
5
6
7
8
9
// ASYNC 模式 
@Subscribe (threadMode = ThreadMode.ASYNC)
public void onAsyncEvent(final AsyncEvent event){
final String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

发布者代码:(PublisherDialogFragment.java)
1
2
3
4
5
6
7
8
9
10
11
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new AsyncEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new AsyncEvent(Thread.currentThread ().toString ()));
}
break;

下面是整个工程全部的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
setTitle ("Subscriber");
}

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

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

// POSTING 模式
@Subscribe (threadMode = ThreadMode.POSTING)
public void onPostingEvent(final PostingEvent event){
String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

// MAIN 模式
@Subscribe (threadMode = ThreadMode.MAIN)
public void onMainEvent(final MainEvent event){
String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

// MAIN_ORDER 模式
@Subscribe (threadMode = ThreadMode.MAIN_ORDERED)
public void onMainOrderEvent(final MainOrderEvent event){
Log.i (TAG, "onMainOrderEvent: enter @" + SystemClock.uptimeMillis ());
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (Thread.currentThread ().toString ());
try {
TimeUnit.SECONDS.sleep (1);
} catch (InterruptedException e) {
e.printStackTrace ();
}
Log.i (TAG, "onMainOrderEvent: exit @" + SystemClock.uptimeMillis ());
}

// BACKGROUND 模式
@Subscribe (threadMode = ThreadMode.BACKGROUND)
public void onBackgroundEvent(final BackgroundEvent event){
final String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

// ASYNC 模式
@Subscribe (threadMode = ThreadMode.ASYNC)
public void onAsyncEvent(final AsyncEvent event){
final String threadInfo = Thread.currentThread ().toString ();
runOnUiThread (()->{
setPublisherThreadInfo (event.threadInfo);
setSubscriberThreadInfo (threadInfo);
});
}

private void setPublisherThreadInfo(String threadInfo){
setTextView (R.id.tv_publisher_thread, threadInfo);
}

private void setSubscriberThreadInfo(String threadInfo){
setTextView (R.id.tv_subscriber_thread, threadInfo);
}

// Run on UI Thread
private void setTextView(int resId, String text){
TextView textView = findViewById (resId);
textView.setText (text);
textView.setAlpha (0.5f);
textView.animate ().alpha (1).start ();
}

public void showDialogFragment(View view) {
// Display DialogFragment
PublisherDialogFragment fragment = new PublisherDialogFragment();
fragment.show (getSupportFragmentManager (), "publisher");
}
}

PublisherDialogFragment.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class PublisherDialogFragment extends DialogFragment {
private static final String TAG = "PublisherDialogFragment";
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder (getActivity ());
builder.setTitle ("Publisher");
String [] items = new String[]{"Posting", "Main", "MainOrder", "Background", "Async"};
builder.setItems (items, (dialog, which) -> {
switch (which){
case 0: // Posting Mode
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new PostingEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new PostingEvent(Thread.currentThread ().toString ()));
}
break;
case 1: // Main Mode
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new MainEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new MainEvent(Thread.currentThread ().toString ()));
}
break;

case 2: // Main_Order Mode
Log.i (TAG, "onCreateDialog: before @" + SystemClock.uptimeMillis ());
EventBus.getDefault ().post (new MainOrderEvent(Thread.currentThread ().toString ()));
Log.i (TAG, "onCreateDialog: after @" + SystemClock.uptimeMillis ());
break;

case 3: // BACKGROUND Mode
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new BackgroundEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new BackgroundEvent(Thread.currentThread ().toString ()));
}
break;

case 4: // ASYNC Mode
if(Math.random () > 0.5f){
new Thread("002"){
@Override
public void run() {
EventBus.getDefault ().post (new AsyncEvent(Thread.currentThread ().toString ()));
}
}.start ();
}else {
EventBus.getDefault ().post (new AsyncEvent(Thread.currentThread ().toString ()));
}
break;
default:
break;
}
});
return builder.create ();
}
}

activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<ImageView
android:id="@+id/iv_emoji"
android:layout_centerInParent="true"
android:layout_width="200dp"
android:layout_height="200dp"/>

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_height="wrap_content">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Publisher:"/>

<TextView
android:id="@+id/tv_publisher_thread"
android:textColor="#00f"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subscriber:"/>

<TextView
android:id="@+id/tv_subscriber_thread"
android:textColor="#f00"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="20dp"
android:layout_marginEnd="20dp"
android:onClick="showDialogFragment"
android:background="@drawable/ic_add"
/>
</RelativeLayout>

以上的内容就是 EventBus 的基本使用方法与线程模式的总结了。

参考资料

1、EventBus: Events for Android

2、维基百科 —— 发布 / 订阅

欢迎关注我的其它发布渠道