概述
EventBus 是一款针对 Android 优化的发布–订阅事件总线。它简化了应用程序内各组件间、组件与后台线程间的通信。其优点是开销小,代码更优雅,以及将发送者和接收者解耦。
EventBus 的三要素 :
Event:事件。可以是任意类型的对象。
Subscriber:事件订阅者。在 EventBus 3.0 之前消息处理只能使用 4 种特定的方法,它们分别代表 4 种线程模型。而在 EventBus 3.0 之后,事件处理的方法可以随便起名,但是需要添加一个注解 @Subscribe,并指定线程模型(默认为 POSTING).
Publisher:事件发布者。可调用 post(Object) 在任意线程任意位置发送事件。可自己实例化 EventBus 对象,但一般使用 EventBus.getDefault() 就可以。根据 post 函数参数的类型,会自动调用订阅相关类型事件的函数。
EventBus 的四种 ThreadMode(线程模型) :
POSTING(默认):发布事件和接收事件在同一线程。在事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至可能会引起 ANR。
MAIN:事件的处理会在 UI 线程中执行。同样事件处理的时间不能太长。
BACKGROUND:如果发布事件在 UI 线程,那么接收事件在新线程中。如果发布事件在子线程,那么接收事件直接在此线程中执行。在此事件处理函数中禁止进行 UI 更新操作。
ASYNC:无论事件在哪个线程中发布,该事件处理函数都会在新建的子线程中执行。同样,此事件处理函数中禁止进行 UI 更新操作。
基本用法
EventBus 使用步骤 :
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 MessageEvent { } EventBus.getDefault().register(this ); EventBus.getDefault().post(new MessageEvent ()); @Subscribe (threadMode = ThreadMode.MAIN)public void method (MessageEvent messageEvent) { } EventBus.getDefault().unregister(this );
应用举例
添加依赖库
1 implementation 'org.greenrobot:eventbus:3.1.1'
定义消息事件类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class MessageEvent { private String msg; public MessageEvent (String msg) { this .msg = msg; } public String getMsg () { return msg; } public void setMsg (String msg) { this .msg = msg; } }
注册和取消订阅事件
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 MainActivity extends AppCompatActivity { private static final String TAG = "TAGMainActivity" ; private Button btnJump; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this ); btnJump = findViewById(R.id.btn_jump); btnJump.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { startActivity(new Intent (MainActivity.this ,SecondActivity.class)); } }); } @Subscribe (threadMode = ThreadMode.MAIN) public void method (MessageEvent messageEvent) { Toast.makeText(this ,messageEvent.getMsg(),Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy () { super .onDestroy(); EventBus.getDefault().unregister(this ); } }
事件订阅者处理事件
1 2 3 4 @Subscribe (threadMode = ThreadMode.MAIN)public void method (MessageEvent messageEvent) { Toast.makeText(this ,messageEvent.getMsg(),Toast.LENGTH_SHORT).show(); }
事件发布者发布事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class SecondActivity extends AppCompatActivity { private Button btnSendMsg; @Override protected void onCreate (@Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_second); btnSendMsg = findViewById(R.id.btn_sendMsg); btnSendMsg.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { EventBus.getDefault().post(new MessageEvent ("哈哈哈" )); finish(); } }); } }
ProGuard 混淆规则
1 2 3 4 5 6 7 8 9 10 -keepattributes *Annotation* -keepclassmembers class * { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # Only required if you use AsyncExecutor -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
粘性事件
除了普通事件外,EventBus 还支持粘性事件,就是在发送事件之后再订阅该事件也能接收到该事件。
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 public class MainActivity extends AppCompatActivity { private static final String TAG = "TAGMainActivity" ; private Button btnJump,btnRegist; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnJump = findViewById(R.id.btn_jump); btnRegist = findViewById(R.id.btn_regist); btnJump.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { startActivity(new Intent (MainActivity.this ,SecondActivity.class)); } }); btnRegist.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { if (!EventBus.getDefault().isRegistered(MainActivity.this )){ EventBus.getDefault().register(MainActivity.this ); } } }); } @Subscribe (threadMode = ThreadMode.POSTING,sticky = true ) public void method (MessageEvent messageEvent) { Toast.makeText(this ,messageEvent.getMsg(),Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy () { super .onDestroy(); EventBus.getDefault().unregister(this ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class SecondActivity extends AppCompatActivity { private Button btnSendMsg; @Override protected void onCreate (@Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_second); btnSendMsg = findViewById(R.id.btn_sendMsg); btnSendMsg.setOnClickListener(new View .OnClickListener() { @Override public void onClick (View v) { EventBus.getDefault().postSticky(new MessageEvent ("哈哈哈" )); finish(); } }); } }
链接
参考资料:
GitHub
Android 进阶之光