Android Java 实现事件总线
事件总线(Event Bus)是一种在 Android 开发中常用的组件间通信机制,它可以实现组件间的解耦通信。以下是几种在 Android Java 项目中实现事件总线的方式:
1. 使用第三方库(推荐)
GreenRobot EventBus
添加依赖:
implementation 'org.greenrobot:eventbus:3.3.1'
基本使用:
- 定义事件类:
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
- 注册/注销订阅者(通常在 Activity/Fragment 中):
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
- 声明订阅方法:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show();
}
- 发布事件:
EventBus.getDefault().post(new MessageEvent("Hello EventBus!"));
2. 自定义简单事件总线
实现代码
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class SimpleEventBus {
private static volatile SimpleEventBus instance;
private final Map<Class<?>, List<Subscriber>> subscribersMap = new HashMap<>();
private final Executor executor = Executors.newCachedThreadPool();
public static SimpleEventBus getDefault() {
if (instance == null) {
synchronized (SimpleEventBus.class) {
if (instance == null) {
instance = new SimpleEventBus();
}
}
}
return instance;
}
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
Method[] methods = subscriberClass.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Subscribe.class)) {
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1) {
throw new IllegalArgumentException("Subscribe method must have exactly 1 parameter");
}
Class<?> eventType = parameterTypes[0];
Subscriber subscriberWrapper = new Subscriber(new WeakReference<>(subscriber), method);
synchronized (this) {
List<Subscriber> subscribers = subscribersMap.get(eventType);
if (subscribers == null) {
subscribers = new ArrayList<>();
subscribersMap.put(eventType, subscribers);
}
subscribers.add(subscriberWrapper);
}
}
}
}
public void unregister(Object subscriber) {
synchronized (this) {
for (List<Subscriber> subscribers : subscribersMap.values()) {
for (int i = subscribers.size() - 1; i >= 0; i--) {
Subscriber subscriberWrapper = subscribers.get(i);
Object target = subscriberWrapper.reference.get();
if (target == null || target == subscriber) {
subscribers.remove(i);
}
}
}
}
}
public void post(Object event) {
Class<?> eventClass = event.getClass();
List<Subscriber> subscribers;
synchronized (this) {
subscribers = subscribersMap.get(eventClass);
}
if (subscribers != null && !subscribers.isEmpty()) {
for (Subscriber subscriber : subscribers) {
executor.execute(() -> subscriber.invoke(event));
}
}
}
private static class Subscriber {
private final WeakReference<Object> reference;
private final Method method;
private final ThreadMode threadMode;
Subscriber(WeakReference<Object> reference, Method method) {
this.reference = reference;
this.method = method;
this.method.setAccessible(true);
Subscribe annotation = method.getAnnotation(Subscribe.class);
this.threadMode = annotation.threadMode();
}
void invoke(Object event) {
Object target = reference.get();
if (target == null) return;
try {
if (threadMode == ThreadMode.MAIN) {
new Handler(Looper.getMainLooper()).post(() -> {
try {
method.invoke(target, event);
} catch (Exception e) {
e.printStackTrace();
}
});
} else {
method.invoke(target, event);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public @interface Subscribe {
ThreadMode threadMode() default ThreadMode.POSTING;
}
public enum ThreadMode {
POSTING, // 与发布者在同一线程
MAIN // 主线程
}
}
使用示例
- 定义事件:
public class CustomEvent {
public String data;
public CustomEvent(String data) {
this.data = data;
}
}
- 注册和订阅:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SimpleEventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
SimpleEventBus.getDefault().unregister(this);
}
@SimpleEventBus.Subscribe(threadMode = SimpleEventBus.ThreadMode.MAIN)
public void onCustomEvent(CustomEvent event) {
Toast.makeText(this, event.data, Toast.LENGTH_SHORT).show();
}
}
- 发布事件:
SimpleEventBus.getDefault().post(new CustomEvent("Hello from SimpleEventBus!"));