EventBus是一个Android优化的publish/subscribe消息事件总线,简化了应用程序内各个组件间、组件与后台线程间的通信。
EventBus的使用步骤
在build.gradle中添加依赖
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [ eventBusIndex : 'com.example.myapplication.MyEventBusAppIndex' ]
}
}
}
}
//上面的com.example.myapplication是自己的功能包名
dependencies {
implementation 'org.greenrobot:eventbus:3.1.1'
annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}
注册与反注册
@Override
public void onStart(){
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop(){
super.onStop();
EventBus.getDefault().unregister(this);
}
定义事件
public class MessageEvent {
private MessageEvent messageevent;
public MessageEvent(MessageEvent messageevent) {
this.messageevent = messageevent;
}
public MessageEvent getMessageEvent() {
return messageevent;
}
public void setMessageEvent(MessageEvent messageevent) {
this.messageevent = messageevent;
}
}
订阅事件(注解+方法指定参数)
//参数1:四种线程模型
//参数2:黏性事件,事件处理函数会在Activity UI创建之前,利用黏性事件,可以在创建完UI后再运行一次
//参数3:优先级,例如有两个OnEvent与threadMode相同的Activity,优先级越高,越早执行,默认为0。
//因为事件有继续分发性,若是不想让以后的Activity也接收,可以利用优先级
//EventBus.getDefault().cancelEventDelivery(message);来停止
@Subscribe(threadMode = ThreadMode.MAIN)
public void OnEvent(MessageEvent messageevent) {
.....
}
线程模型 | 说明 |
---|---|
POSTING | 默认,表示事件处理函数的线程与事件发布的线程为同一个 |
MAIN | 表示事件处理函数的线程在主线程(UI)线程中,不能进行耗时操作 |
BACKGROUND | 表示事件处理函数的线程在后台线程中,不能进行UI操作 如果发布事件在主线程里,那事件处理函数则在后台开新线程 如果发布事件在后台线程里,则事件处理函数在同一个 |
ASYNC | 表示无论事件发布的线程在哪一个,事件处理函数的线程都会新建一个子线程,不能进行UI |
发布事件(发送消息)
EventBus.getDefault().post(new MessageEvent());
粘性事件
//@Subscribe注解中加入:sticky = true
//作用:延时消费 或者 未初始化
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onMessageEvent(UserInfo user) {
//消费消息
tv.setText(user.toString());
Log.e("netease >>>", user.toString());
}
//priority优先级越高,数值越大,默认都为0
@Subscribe(threadMode = ThreadMode.MAIN, priority = 10)
public void onMessageEvent2(UserInfo user) {
//消费消息
tv.setText(user.toString());
Log.e("netease >>>", user.toString());
}
//如果两个订阅方法可以同时接收
//priority数值越大,优先级越高,默认为0
EventBus的使用
订阅事件
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
public class EventBusActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event_bus);
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(EventBus.getDefault().isRegistered(this)){
EventBus.getDefault().unregister(this);
}
}
//订阅方法
@Subscribe
public void event(String string){
Log.e("test >>>", string);
}
//点击事件
public void jump(View view) {
startActivity(new Intent(this, SendActivity.class));
}
}
发送事件
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import org.greenrobot.eventbus.EventBus;
public class SendActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send);
}
//点击事件
public void post(View view) {
//发布事件
EventBus.getDefault().post("simon");
}
}
编译时索引的原理是通过编译时注解处理器生成索引表,记录事件 —— 订阅关系的映射,在运行时直接加载索引表。如果不使用编译时索引,在注册订阅者时就需要递归反射查找类本身与父类中使用@Subscribe注解修饰的方法,影响性能;
@Subscribe 订阅方法是通过反射调用的,在编译时没有直接调用,如果不增加反混淆规则的话,在运行时会出现找不到方法名的情况。
参考链接:
Android | 这是一份详细的 EventBus 使用教程 - 简书 (jianshu.com)
【Android开发--新手必看篇】依赖框架EventBus的使用_org.greenrobot:eventbus 依赖包-CSDN博客