要实现fragment与activity之前的通讯,或者service与activity的通讯,我们可以有好几种方式实现
1、广播
2、回调接口
3、eventBus、RxBus
4、其他
封装了一下RxBus的使用,废话不多说,直接上源码:
GitHub源码
1、ThreadMode,所执行的线程
public enum ThreadMode {
/**
* current thread
*/
CURRENT_THREAD,
/**
* android main thread
*/
MAIN,
/**
* new thread
*/
NEW_THREAD
}
2、Subscribe,注解
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
int code() default -1;
ThreadMode threadMode() default ThreadMode.CURRENT_THREAD;
}
3、SubscriberMethod,存储订阅者的相关信息,并提供invoke调用
public class SubscriberMethod {
public Method method;
public ThreadMode threadMode;
public Class> eventType;
public Object subscriber;
public int code;
public boolean originalIsPrimitive;//原始类型是否为基本类型
public SubscriberMethod(Object subscriber, Method method, Class> eventType, int code, ThreadMode threadMode, boolean originalIsPrimitive) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.subscriber = subscriber;
this.code = code;
this.originalIsPrimitive = originalIsPrimitive;
}
/**
* 调用方法
*
* @param o 参数
*/
public void invoke(Object o) {
try {
Class[] parameterType = method.getParameterTypes();
if (parameterType != null && parameterType.length == 1) {
method.invoke(subscriber, o);
} else if (parameterType == null || parameterType.length == 0) {
method.invoke(subscriber);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
4、PrimitiveBox,基本类型转换成对象类型
public class PrimitiveBox {
/**
* 装箱
*
* @param target 目标类
* @return 转换后的Class
*/
public static Class> mantle(final Class> target) {
if (boolean.class.equals(target)) {
return Boolean.class;
} else if (char.class.equals(target)) {
return Character.class;
} else if (byte.class.equals(target)) {
return Byte.class;
} else if (short.class.equals(target)) {
return Short.class;
} else if (int.class.equals(target)) {
return Integer.class;
} else if (long.class.equals(target)) {
return Long.class;
} else if (float.class.equals(target)) {
return Float.class;
} else if (double.class.equals(target)) {
return Double.class;
} else {
return target;
}
}
}
5、BusData,默认的事件类型
public class BusData {
String id;
String status;
public BusData() {}
public BusData(String id, String status) {
this.id = id;
this.status = status;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
6、RxBus,核心类
public class RxBus {
public static final String TAG = "RxBus_log";
private static volatile RxBus defaultInstance;
/**
* key==》订阅者对象,value==》订阅事件(disposable )
*/
private Map> subscriptionsByEventType = new HashMap<>();
/**
* key==》订阅者对象,value==》事件类型
*
* value是 根据Key所注解的方法的参数类型确定,默认==》BusData,如:
*
* 注解方法==》a(),则value==》BusData
* 注解方法==》a(String str),则value==》String
*/
private Map> eventTypesBySubscriber = new HashMap<>();
/**
* key==》事件类型,value==》订阅者信息
*
* value信息包括:订阅者对象(subscriber), 方法名(method), 事件类型(eventType), 事件code(code), 线程类型(threadMode)
*/
private Map> subscriberMethodByEventType = new HashMap<>();
private final Subject bus;
private RxBus() {
this.bus = PublishSubject.create().toSerialized();
}
public static RxBus getDefault() {
RxBus rxBus = defaultInstance;
if (defaultInstance == null) {
synchronized (RxBus.class) {
rxBus = defaultInstance;
if (defaultInstance == null) {
rxBus = new RxBus();
defaultInstance = rxBus;
}
}
}
return rxBus;
}
/**
* 注册
*
* @param subscriber 订阅者
*/
public void register(Object subscriber) {
YLogUtil.logD2Tag(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@注册@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@--订阅者对象", subscriber);
//根据对象获取类
Class> subClass = subscriber.getClass();
//获取所有方法名
Method[] methods = subClass.getDeclaredMethods();
for (Method method : methods) {
//判断方法是否存在注解
if (method.isAnnotationPresent(Subscribe.class)) {
//获得参数类型
Class[] parameterType = method.getParameterTypes();
//参数不为空 且参数个数为1
if (parameterType != null && parameterType.length == 1) {
Class eventType = parameterType[0];
executeRegistered(subscriber, method, eventType);
} else if (parameterType == null || parameterType.length == 0) {
Class eventType = BusData.class;
executeRegistered(subscriber, method, eventType);
}
}
}
YLogUtil.logD2Tag(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@注册完成@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@--订阅者对象", subscriber);
}
/**
* 取消注册
*
* @param subscriber 订阅者
*/
public void unregister(Object subscriber) {
YLogUtil.logD2Tag(TAG, "###################################取消注册###################################--订阅者对象", subscriber);
//通过订阅者对象,获取对应的事件类型集合
List subscribedTypes = eventTypesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class> eventType : subscribedTypes) {
unSubscribeByEventType(subscriber);
unSubscribeMethodByEventType(subscriber, eventType);
YLogUtil.logD2Tag(TAG, "执行取消注册--订阅者对象", subscriber, "事件类型", eventType);
}
eventTypesBySubscriber.remove(subscriber);
}
YLogUtil.logD2Tag(TAG, "###################################取消注册完成###############################--订阅者对象", subscriber);
}
/**
* 是否注册
*
* @param subscriber 订阅者
* @return
*/
public synchronized boolean isRegistered(Object subscriber) {
boolean isRegistered = eventTypesBySubscriber.containsKey(subscriber);
YLogUtil.logD2Tag(TAG, "************************************判断是否注册******************************--订阅者对象", subscriber, "是?", isRegistered);
return isRegistered;
}
/**
* 执行注册
*
* @param subscriber 订阅者对象
* @param method 方法名
* @param eventType 事件类型
*/
private void executeRegistered(Object subscriber, Method method, Class eventType) {
//判断是否为基本类型
boolean isPrimitive = eventType.isPrimitive();
if (isPrimitive) {
YLogUtil.logD2Tag(TAG, "*********基础类型自动装箱---开始*********装箱前类型", eventType);
eventType = PrimitiveBox.mantle(eventType);
YLogUtil.logD2Tag(TAG, "*********基础类型自动装箱---完成*********装箱后类型", eventType);
}
// key==》订阅者对象,value==》事件类型,保存到map里
addEventTypeToMap(subscriber, eventType);
//获取注解
Subscribe sub = method.getAnnotation(Subscribe.class);
int code = sub.code();
ThreadMode threadMode = sub.threadMode();
//key==》事件类型,value==》订阅者信息,保存到map里
SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode, isPrimitive);
addSubscriberToMap(eventType, subscriberMethod);
//添加到RxJava订阅
addSubscriber(subscriberMethod);
YLogUtil.logD2Tag(TAG, "执行注册---方法:", method, "---事件类型:", eventType);
}
/**
* key==》订阅者对象,value==》事件类型,保存到map里
*
* @param subscriber 订阅者对象
* @param eventType 事件类型
*/
private void addEventTypeToMap(Object subscriber, Class eventType) {
List eventTypes = eventTypesBySubscriber.get(subscriber);
if (eventTypes == null) {
eventTypes = new ArrayList<>();
eventTypesBySubscriber.put(subscriber, eventTypes);
}
if (!eventTypes.contains(eventType)) {
eventTypes.add(eventType);
}
}
/**
* key==》事件类型,value==》订阅者信息,保存到map里
*
* @param eventType 事件类型
* @param subscriberMethod 订阅者信息
*/
private void addSubscriberToMap(Class eventType, SubscriberMethod subscriberMethod) {
List subscriberMethods = subscriberMethodByEventType.get(eventType);
if (subscriberMethods == null) {
subscriberMethods = new ArrayList<>();
subscriberMethodByEventType.put(eventType, subscriberMethods);
}
if (!subscriberMethods.contains(subscriberMethod)) {
subscriberMethods.add(subscriberMethod);
}
}
/**
* 用RxJava添加订阅者
*
* @param subscriberMethod 订阅者信息
*/
@SuppressWarnings("unchecked")
private void addSubscriber(final SubscriberMethod subscriberMethod) {
Flowable flowable;
if (subscriberMethod.code == -1) {
flowable = toObservable(subscriberMethod.eventType);
} else {
flowable = toObservable(subscriberMethod.code, subscriberMethod.eventType);
}
Disposable subscription = postToObservable(flowable, subscriberMethod)
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
callEvent(subscriberMethod, o);
}
});
//key==》订阅者对象,value==》订阅事件(disposable )
addSubscriptionToMap(subscriberMethod.subscriber, subscription);
}
/**
* 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者
*
* @param eventType 事件类型
* @return return
*/
public Flowable toObservable(Class eventType) {
//ofType(class) 指定某个类型的class,过滤属于这个类型的的结果,其它抛弃
return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(eventType);
}
/**
* 根据传递的code和 eventType 类型返回特定类型(eventType)的 被观察者
*
* @param code 事件code
* @param eventType 事件类型
*/
private Flowable toObservable(final int code, final Class eventType) {
//ofType(class) 指定某个类型的class,过滤属于这个类型的的结果,其它抛弃
return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(Message.class)
//采用filter()变换操作符
.filter(new Predicate() {
// 根据test()的返回值 对被观察者发送的事件进行过滤 & 筛选
// a. 返回true,则继续发送
// b. 返回false,则不发送(即过滤)
@Override
public boolean test(Message o) throws Exception {
return o.getCode() == code && eventType.isInstance(o.getObject());
}
// map操作符,Function,只要类型为Object的子类就可以进行转换
}).map(new Function() {
@Override
public Object apply(Message o) throws Exception {
return o.getObject();
}
}).cast(eventType);
}
/**
* 用于处理订阅事件在那个线程中执行
*
* @param observable 订阅事件
* @param subscriberMethod 订阅者信息
* @return Observable
*/
private Flowable postToObservable(Flowable observable, SubscriberMethod subscriberMethod) {
Scheduler scheduler;
switch (subscriberMethod.threadMode) {
case MAIN:
scheduler = AndroidSchedulers.mainThread();
break;
case NEW_THREAD:
scheduler = Schedulers.newThread();
break;
case CURRENT_THREAD:
scheduler = Schedulers.trampoline();
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscriberMethod.threadMode);
}
return observable.observeOn(scheduler);
}
/**
* key==》订阅者对象,value==》订阅事件(disposable )
*
* @param subscriber 订阅者对象
* @param disposable 订阅事件
*/
private void addSubscriptionToMap(Object subscriber, Disposable disposable) {
List disposables = subscriptionsByEventType.get(subscriber);
if (disposables == null) {
disposables = new ArrayList<>();
subscriptionsByEventType.put(subscriber, disposables);
}
if (!disposables.contains(disposable)) {
disposables.add(disposable);
}
}
/**
* 回调到订阅者的方法中
*
* @param subscriberMethod 订阅者信息
* @param object 事件类型对象
*/
private void callEvent(SubscriberMethod subscriberMethod, Object object) {
YLogUtil.logD2Tag(TAG, "执行回调----订阅者对象", subscriberMethod.subscriber, "方法", subscriberMethod.method, "事件类型对象", object);
//因为最终发送的为事件类型对象
//所以需要通过事件类型对象,获取对应的事件类型
Class eventClass = object.getClass();
//通过事件类型,获取订阅者信息
List subscriberMethodList = subscriberMethodByEventType.get(eventClass);
//判断订阅者信息是否相同,并回调订阅者
if (subscriberMethodList != null && subscriberMethodList.size() > 0) {
for (SubscriberMethod tmpSubscriberMethod : subscriberMethodList) {
if (tmpSubscriberMethod.code == subscriberMethod.code && subscriberMethod.subscriber.equals(tmpSubscriberMethod.subscriber)
&& subscriberMethod.method.equals(tmpSubscriberMethod.method)) {
tmpSubscriberMethod.invoke(object);
YLogUtil.logD2Tag(TAG, "回调成功----订阅者对象", subscriberMethod.subscriber, "方法", subscriberMethod.method, "事件类型对象", object);
}
}
}
}
/**
* 移除订阅者对象对应的订阅事件
*
* @param subscriber 订阅者对象
*/
private void unSubscribeByEventType(Object subscriber) {
List disposables = subscriptionsByEventType.get(subscriber);
if (disposables != null) {
Iterator iterator = disposables.iterator();
while (iterator.hasNext()) {
Disposable disposable = iterator.next();
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
iterator.remove();
}
}
}
}
/**
* 移除订阅者对象对应的订阅者信息
*
* @param subscriber 订阅者对象
* @param eventType 事件类型
*/
private void unSubscribeMethodByEventType(Object subscriber, Class eventType) {
//通过事件类型,获取订阅者信息
List subscriberMethods = subscriberMethodByEventType.get(eventType);
//判断订阅者信息的订阅者对象是否相同
if (subscriberMethods != null) {
Iterator iterator = subscriberMethods.iterator();
while (iterator.hasNext()) {
SubscriberMethod subscriberMethod = iterator.next();
if (subscriberMethod.subscriber.equals(subscriber)) {
iterator.remove();
}
}
}
}
public void send(int code, Object o) {
Message message = new Message(code, o);
bus.onNext(message);
YLogUtil.logD2Tag(TAG, "发送RxBus", o);
}
public void post(Object o) {
bus.onNext(o);
}
public void send(int code) {
Message message = new Message(code, new BusData());
bus.onNext(message);
YLogUtil.logD2Tag(TAG, "发送RxBus", message.object);
}
private class Message {
private int code;
private Object object;
public Message() {
}
private Message(int code, Object o) {
this.code = code;
this.object = o;
}
private int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
private Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
}
RxBus使用方式
一、注册RxBus:
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RxBus.getDefault().register(this);
}
@SuppressLint("测试1,参数为String类型")
@Subscribe(code = 1001, threadMode = ThreadMode.MAIN)
public void rxBusTest1(String msg) {
}
@SuppressLint("测试2,参数为int基本数据类型")
@Subscribe(code = 1002, threadMode = ThreadMode.MAIN)
public void rxBusTest2(int type) {
}
@SuppressLint("测试3,参数为自定义对象")
@Subscribe(code = 1003, threadMode = ThreadMode.MAIN)
public void rxBusTest3(MsgData msgData) {
}
@SuppressLint("测试4,无参")
@Subscribe(code = 1004, threadMode = ThreadMode.MAIN)
public void rxBusTest4() {
}
@Override
protected void onDestroy() {
super.onDestroy();
RxBus.getDefault().unregister(this);
}
}
二、发送RxBus:
RxBus.getDefault().send(1001,"hihi");
RxBus.getDefault().send(1002,123);
RxBus.getDefault().send(1003,new MsgData(111,"test"));
RxBus.getDefault().send(1004);
public class MsgData {
public int code;
public String msg;
public MsgData (int code, String msg) {
this.code = code;
this.msg = msg;
}
}
混淆:
#如RxBus所在包名为com.cn.rxbus
#Rxbus混淆
-dontwarn com.cn.rxbus.**
-keep class com.cn.rxbus.** { *;}
-keepattributes *Annotation
-keep @com.cn.rxbus.Subscribe class * {*;}
-keep class * {
@com.cn.rxbus.Subscribe ;
}
-keepclassmembers class * {
@com.cn.rxbus.Subscribe ;
}
#Rxbus混淆end