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<Object, List<Disposable>> subscriptionsByEventType = new HashMap<>();

    /**
     * key==》订阅者对象,value==》事件类型
     * <p>
     * value是 根据Key所注解的方法的参数类型确定,默认==》BusData,如:
     * <p>
     * 注解方法==》a(),则value==》BusData
     * 注解方法==》a(String str),则value==》String
     */
    private Map<Object, List<Class>> eventTypesBySubscriber = new HashMap<>();

    /**
     * key==》事件类型,value==》订阅者信息
     * <p>
     * value信息包括:订阅者对象(subscriber), 方法名(method), 事件类型(eventType), 事件code(code), 线程类型(threadMode)
     */
    private Map<Class, List<SubscriberMethod>> subscriberMethodByEventType = new HashMap<>();

    private final Subject<Object> 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<Class> 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<Class> 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<SubscriberMethod> 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<Object>() {
                    @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 <T> Flowable<T> toObservable(Class<T> eventType) {
        //ofType(class)  指定某个类型的class,过滤属于这个类型的的结果,其它抛弃
        return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(eventType);
    }

    /**
     * 根据传递的code和 eventType 类型返回特定类型(eventType)的 被观察者
     *
     * @param code      事件code
     * @param eventType 事件类型
     */
    private <T> Flowable<T> toObservable(final int code, final Class<T> eventType) {
        //ofType(class)  指定某个类型的class,过滤属于这个类型的的结果,其它抛弃
        return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(Message.class)
                //采用filter()变换操作符
                .filter(new Predicate<Message>() {
                    // 根据test()的返回值 对被观察者发送的事件进行过滤 & 筛选
                    // a. 返回true,则继续发送
                    // b. 返回false,则不发送(即过滤)
                    @Override
                    public boolean test(Message o) throws Exception {
                        return o.getCode() == code && eventType.isInstance(o.getObject());
                    }
                    // map操作符,Function<Object,Object>,只要类型为Object的子类就可以进行转换
                }).map(new Function<Message, Object>() {
                    @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<Disposable> 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<SubscriberMethod> 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<Disposable> disposables = subscriptionsByEventType.get(subscriber);
        if (disposables != null) {
            Iterator<Disposable> 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<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType);
        //判断订阅者信息的订阅者对象是否相同
        if (subscriberMethods != null) {
            Iterator<SubscriberMethod> 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 <fields>;
}
-keepclassmembers class * {
    @com.cn.rxbus.Subscribe <methods>;
}
#Rxbus混淆end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值