EventBus事件巴士概念:采用的观察者设计模式
EventBus是一个发布/订阅的事件总线.EventBus模式 - 也被称为MessageBus或者发布者/订阅者public/subscribe消息总线,可以让应用程序内部各组件间,组件与后台线程间的通讯(比如请求网络后返回数据时,通过Handler或Broadcast与UI交互,两个Fragment之间需要通过Listener通信...),但是他们之间并不相互知晓.
基于事件总线管理/订阅/分布模式.事件响应有更多的线程选择,EventBus可以向不同的线程发布事件,支持Sticky Event
使用时需要先注册订阅,然后向订阅者分发消息数据即可.包含4个成分:发布者,订阅者,事件,总线.订阅者可以订阅多个事件,发送者可以发布任何事件,发布者同时可以是订阅者.分订阅,注册,发布,取消注册等步骤.
EventBus和Otto相比更节约内存,且运行效率更高.
//EventBus
实际上和广播非常相似
,
只不过使用简单
,
代码量少
,
性能更好
.
//MainActivity 就是接受消息的类 , 你的事件在哪接收 , 就在哪个类进行 EventBus 的注册和解除操作 .
//MainActivity 就是接受消息的类 , 你的事件在哪接收 , 就在哪个类进行 EventBus 的注册和解除操作 .
//1.
注册
EventBus
参数就是上下文
// 注意 : 有注册 EventBus, 就必须有解除注册的操作 ( 一般在 OnDestroy 方法里执行解除注册 ), 防止内存泄漏 , 注册一个界面只能注册一次
// 注意 : 有注册 EventBus, 就必须有解除注册的操作 ( 一般在 OnDestroy 方法里执行解除注册 ), 防止内存泄漏 , 注册一个界面只能注册一次
EventBus.getDefault().register(this);
//2.
在
onDestroy
里解除
EventBus,
参数是上下文
@Override
protected void onDestroy() {
EventBus. getDefault().unregister( this);
@Override
protected void onDestroy() {
EventBus. getDefault().unregister( this);
super.onDestroy();
}
//
根据点击事件
,
跳转到发送事件的
Activity
里
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id. button:
Intent intent = new Intent(MainActivity. this, EventBusSendActivity. class);
startActivity(intent);
break;
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id. button:
Intent intent = new Intent(MainActivity. this, EventBusSendActivity. class);
startActivity(intent);
break;
}
}
创建一个EventBus类
3.EventBus
消息类
,
一个容器
,
负责放一些东西
,
方便另一个订阅者
(
接收者
)
获取消息
public class EventBusMessage {
// 定义了发送的消息必须是 String 类型
public String Message;
public EventBusMessage(String message) {
Message = message;
}
// 定义了发送的消息必须是 String 类型
public String Message;
public EventBusMessage(String message) {
Message = message;
}
}
创建一个Activity,用来发送数据
//
根据点击事件
,
发送数据
//4.
使用
EventBus
发送事件
,
使用
Post
方法
,
参数也必须是
EventBus
消息对且要和接收的保持一致
EventBus. getDefault().post( new EventBusMessage( "hatsune39"));
EventBus. getDefault().post( new EventBusMessage( "hatsune39"));
finish();
//5.
接收消息
,
参数就是我们定义的
Eventbus
消息类
,
和发送消息类必须是同一个
,
加注解
// 提示 : 在写接收消息的方法时 , 方法名可以自定义 , 但是权限必须是 public, 参数必须是一个
@Subscribe(threadMode = ThreadMode. MAIN) // 注解
// @Subscribe(threadMode = ThreadMode.BACKGROUND)
// @Subscribe(threadMode = ThreadMode.POSTING)
// @Subscribe(threadMode = ThreadMode.ASYNC)
public void MessageHatsune(EventBusMessage eventBusMessage){
// 显示接收的消息 , 从这个类里拿属性
textView.setText(eventBusMessage. Message);
// 提示 : 在写接收消息的方法时 , 方法名可以自定义 , 但是权限必须是 public, 参数必须是一个
@Subscribe(threadMode = ThreadMode. MAIN) // 注解
// @Subscribe(threadMode = ThreadMode.BACKGROUND)
// @Subscribe(threadMode = ThreadMode.POSTING)
// @Subscribe(threadMode = ThreadMode.ASYNC)
public void MessageHatsune(EventBusMessage eventBusMessage){
// 显示接收的消息 , 从这个类里拿属性
textView.setText(eventBusMessage. Message);
}
EventBus黏性事件
主窗体中
@Override
public void onClick(View v) {
switch (v.getId()) {
// 发送消息给接收页面 , 跳转到接收页面
case R.id. button:
EventBus. getDefault().postSticky( new EventBusStickyMessage( " 我是主页面发送过来的粘性事件 "));
// 字节码文件
Intent intent = new Intent(MainActivity. this, EventBusReceiveActivity. class);
startActivity(intent);
break;
}
public void onClick(View v) {
switch (v.getId()) {
// 发送消息给接收页面 , 跳转到接收页面
case R.id. button:
EventBus. getDefault().postSticky( new EventBusStickyMessage( " 我是主页面发送过来的粘性事件 "));
// 字节码文件
Intent intent = new Intent(MainActivity. this, EventBusReceiveActivity. class);
startActivity(intent);
break;
}
}
新窗体中
public class EventBusReceiveActivity
extends AppCompatActivity
implements View.OnClickListener {
private Button
button;
private TextView textView;
boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_event_bus_receive);
initView();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id. button:
// 一旦注册了 EventBus 就会接收到消息
if ( flag){
EventBus. getDefault().register( this);
flag = false;
}
break;
}
}
// 在 onDestroy 里解除 Eventbus 注册
// 注意 : 这里比普通的解除注册还多异步 , 就是移除黏性事件 ( 是移除所有还是一个 , 看需求 )
@Override
protected void onDestroy() {
EventBus. getDefault().removeAllStickyEvents();
EventBus. getDefault().unregister( this);
super.onDestroy();
}
// 接收黏性事件 多了一个属性 sticky, 改为 true
@Subscribe(threadMode = ThreadMode. MAIN,sticky = true)
public void messageHatsune(EventBusStickyMessage eventBusStickyMessage){
textView.setText(eventBusStickyMessage. message);
}
private void initView() {
button = (Button) findViewById(R.id. button);
textView = (TextView) findViewById(R.id. textView);
button.setOnClickListener( this);
private TextView textView;
boolean flag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_event_bus_receive);
initView();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id. button:
// 一旦注册了 EventBus 就会接收到消息
if ( flag){
EventBus. getDefault().register( this);
flag = false;
}
break;
}
}
// 在 onDestroy 里解除 Eventbus 注册
// 注意 : 这里比普通的解除注册还多异步 , 就是移除黏性事件 ( 是移除所有还是一个 , 看需求 )
@Override
protected void onDestroy() {
EventBus. getDefault().removeAllStickyEvents();
EventBus. getDefault().unregister( this);
super.onDestroy();
}
// 接收黏性事件 多了一个属性 sticky, 改为 true
@Subscribe(threadMode = ThreadMode. MAIN,sticky = true)
public void messageHatsune(EventBusStickyMessage eventBusStickyMessage){
textView.setText(eventBusStickyMessage. message);
}
private void initView() {
button = (Button) findViewById(R.id. button);
textView = (TextView) findViewById(R.id. textView);
button.setOnClickListener( this);
}
EventBus消息类
public class EventBusStickyMessage {
public String message;
public EventBusStickyMessage(String message) {
this. message = message;
}
}
public String message;
public EventBusStickyMessage(String message) {
this. message = message;
}
}
接收消息的四种类型:
ThreadMode.
MAIN
表示这个方法在主线程中执行 (非常适合做异步加载,可以将子线程加载到的数据直接设置到UI界面里)
ThreadMode.BACKGROUND
表示该方法在后台执行(也就是子线程执行),不能并发处理.
如果发布者在子线程,那么该方法就在这个子线程执行
如果发布者在主线程,那么该方法会创建一个子线程,在子线程执行.
ThreadMode.POSTING
也表示在后台执行(也就是子线程执行),可以异步并发处理(非常适用于多个线程任务处理,内部有线程池管理,比如请求网络时,用这个方法,他会自动创建线程去请求)
无论发布者是在子线程还是主线程, 该方法都会创建一个子线程,在子线程执行.
ThreadMode.ASYNC
表示该方法和消息发送方在同一个线程中执行.
(注意:在EventBus之前,是通过方法来实现).
switch (v.getId()) { case R.id.btnOk: new Thread(){ @Override public void run() { super.run(); EventBus.getDefault().post(new Message("hatsune39")); //获取线程的名字 Thread.currentThread().getName(); } }.start(); break; } } //5.接收消息,参数就是我们定义的Eventbus消息类,和发送消息类必须是同一个,加注解 //提示:在写接收消息的方法时,方法名可以自定义,但是权限必须是public,参数必须是一个 // //无论如何都在主线程执行里面代码 @Subscribe(threadMode = ThreadMode.MAIN)//注解 public void MessageHatsune(Message message){ Log.d("eventBusThread","ThreadMode.MAIN"+Thread.currentThread().getName()); } //和接收消息同一线程执行里面代码 @Subscribe(threadMode = ThreadMode.POSTING)//注解 public void MessageHatsune1(Message message){ Log.d("eventBusThread","ThreadMode.POSTING"+Thread.currentThread().getName()); } //不论接收消息在什么线程都创建一个子线程执行里面代码 @Subscribe(threadMode = ThreadMode.ASYNC)//注解 public void MessageHatsune2(Message message){ Log.d("eventBusThread","ThreadMode.ASYNC"+Thread.currentThread().getName()); } //如果接收消息在子线程,就在该子线程中执行,如果接收消息在主线程,就创建一个子线程执行里面代码 @Subscribe(threadMode = ThreadMode.BACKGROUND)//注解 public void MessageHatsune3(Message message){ Log.d("eventBusThread","ThreadMode.BACKGROUND"+Thread.currentThread().getName()); }