RxBus-mvp模式下对Rxjav的封装(二)

news/2024/7/3 13:19:44

一、自定义注解,用于标记观察者模式

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RegisterBus {

}
二、定义一个RxBus的类

public class RxBus {
    public static final String TAG = "RxBus";
    private static volatile RxBus instance;//使用volatile关键字声明的变量或对象通常拥有和优化和(或)多线程相关的特殊属性
    //订阅者集合
    private Set<Object> subscribers;

    /**
     * 注册DataBusSubscriber
     */
    public synchronized void register(Object subscriber) {
        subscribers.add(subscriber);
    }

    /**
     * 注销DataBusSubscriber
     */
    public synchronized void unregister(Object subscriber) {
        subscribers.remove(subscriber);
    }

    /**
     * 单例模式
     */
    private RxBus() {
        //因为通常需要复制整个基础数组,所以可变操作(add()set()  remove() 等等)的开销很大
        subscribers = new CopyOnWriteArraySet<>();
    }

    public static synchronized RxBus getInstance() {
        if (instance == null) {
            synchronized (RxBus.class) {
                if (instance == null) {
                    instance = new RxBus();
                }
            }
        }
        return instance;
    }

    /**
     * 包装处理过程
     */
    public void chainProcess(Func1 func) {
        Observable.just("")
                .subscribeOn(Schedulers.io())//指定处理过程在IO线程
                .map(func)//包装处理过程
                .observeOn(AndroidSchedulers.mainThread())//指定事件消费在主线程
                .subscribe(new Action1<Object>() {
                    @Override
                    public void call(Object data) {
                          if(data==null){
                              return;
                          }
                        send(data);
                    }
                });

    }

    private void send(Object data) {
        for (Object subscriber : subscribers) {
           //扫描注解,将数据发送到注册的对象的标记方法
            callMethodByAnnotiation(subscriber,data);
        }
    }

    /**
     * 反射获取对象方法列表,判断
     * 1.是否被注解修饰
     * 2.参数类型是否和data类型一直
     */

    private void callMethodByAnnotiation(Object target, Object data) {
        Method[] methodArray = target.getClass().getDeclaredMethods();
        for(int i=0;i<methodArray.length;i++){
          try {
              if(methodArray[i].isAnnotationPresent(RegisterBus.class)){
                  //@RegisterBus修饰的方法
                  Class paramType = methodArray[i].getParameterTypes()[0];
                  if(data.getClass().getName().equals(paramType.getName())){
                      //参数类型和data类型一样,调用此方法
                      methodArray[i].invoke(target,new Object[]{data});
                  }
              }
          }catch (InvocationTargetException e) {
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          }
        }
    }

}
三、RxBus的测试
public class RxBusTest {
    public static final String  TAG="RxBusTest";
    Presenter presenter;
    @Before
    public void setUp() throws Exception{
        /**
         * 初始化presenter并注册
         */
        presenter=new Presenter(new Manager());
        RxBus.getInstance().register(presenter);
    }
    @After
    public void tearDown(){
        try {
            Thread.sleep(5000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        RxBus.getInstance().unregister(presenter);
    }
    @Test
    public void testGetUser() throws Exception{
        presenter.getUser();
    }
    @Test
    public void testGetOrder()throws Exception
    {
        presenter.getOrder();
    }
    /**
     * 模拟Presenter
     */
    class Presenter  {
        private Manager manager;

        public Presenter(Manager manager) {
            this.manager = manager;
        }

        public void getUser() {
            manager.getUser();
        }

        public void getOrder() {
            manager.getOrder();
        }

        /**
         * 接受数据
         *
         */
        @RegisterBus
        public void onUser(User user){
            Log.d(TAG, "receiver User in thread" + Thread.currentThread());
        }
        @RegisterBus
        public void onOrder(Order order){
            Log.d(TAG, "receiver Order in thread" + Thread.currentThread());
        }

    }

    /**
     * 模拟model
     */
    class Manager {
        public void getUser() {
            RxBus.getInstance().chainProcess(new Func1() {
                @Override
                public Object call(Object o) {
                    Log.d(TAG, "chainProcess getUser start in thread:" + Thread.currentThread());
                    User user = new User();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return user;
                }
            });
        }

        public void getOrder() {
            RxBus.getInstance().chainProcess(new Func1() {
                @Override
                public Object call(Object o) {
                    Log.d(TAG, "chainProcess getUser start in thread:" + Thread.currentThread());
                    Order order = new Order();

                    return order;
                }
            });
        }
    }

    /**
     * 要返回的数据类型
     */
    class User {

    }

    class Order {

    }
}


http://www.niftyadmin.cn/n/3649283.html

相关文章

离子赝势文件_排除离子错误

离子赝势文件Below is a brief overview on how to get started troubleshooting bugs in your Ionic projects. 以下是有关如何开始对Ionic项目中的错误进行故障排除的简要概述。 介绍 (Introduction) There are two main types of bugs that occur when developing in Ionic…

QuickTest底层VB脚本驱动

sample Codes: **** Author: Wally Yu (俞戴龙)*** Import common functions into report function ****Dim fso : set fso createobject("scripting.filesystemobject")executeglobal fso.opentextfile("C:\Framework\FrameworkCore\Common\common.vbs&q…

[收藏]使用 WSE 2.0 从 WS-Routing 转移到 WS-Addressing

使用 WSE 2.0 从 WS-Routing 转移到 WS-Addressing发布日期&#xff1a; 5/202004| 更新日期&#xff1a; 5/20/2004Aaron SkonnardNorthface University适用于&#xff1a;Web Services Enhancements 2.0 for Microsoft.NETWS-Routing 规范WS-Addressing 规范摘要&#xff1a;…

android studio下的sha1值获取

一、首先在app下定义一个文件夹&#xff1a;keystore Build->Generate Signed APK->Create New key store->选择自己项目的keystore下&#xff0c;名字写build->输入密码和其他信息&#xff0c;Alias我写的是build->选择build 二、完成后重复上步骤 Build-&g…

[原创文章] 比较Excel的VBS函数

QTP中Excel的比较 作者&#xff1a;Wally Yu (微博&#xff1a;http://weibo.com/quicktest)最近在SQAForum经常有人提出关于比较两个Excel的值的问题的帖子 例如&#xff1a; http://www.sqaforums.com/showflat.php?Cat0&Number549014&an0&page0#Post549014 htt…

Flutter的HTTP请求

It’s hard to do any sort of development without having to make some form of HTTP request, therefore, we’ll be looking at how to use the http plugin within Flutter. 无需进行某种形式的HTTP请求就很难进行任何类型的开发&#xff0c;因此&#xff0c;我们将研究如…

android上的JAVA8:使用retrolambda

Java8引入了lambda表达式&#xff0c;让许多开发者激动不已&#xff0c;本文介绍如何在Android上使用lambda。 首先下载 java8 sdk &#xff0c;并且配置完成在 build.gradle 中加入编译的依赖&#xff0c;这会使用retrolambda来编译Java代码 buildscript { //开始加入depend…

react 生命挂钩_简而言之,React useContext挂钩

react 生命挂钩Early February 2019, React introduced Hooks as a way to rewrite your components as simple, more manageable, and classless. useContext is one of the built-in Hooks, giving functional components easy access to your context. But before we dive i…