RxBus的封装

要实现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();//参数不为空 且参数个数为1if (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() {@Overridepublic 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,则不发送(即过滤)@Overridepublic boolean test(Message o) throws Exception {return o.getCode() == code && eventType.isInstance(o.getObject());}// map操作符,Function,只要类型为Object的子类就可以进行转换}).map(new Function() {@Overridepublic 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{@Overrideprotected 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() {}@Overrideprotected 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

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章