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()); }