(4.6.22)来吧,是时候撸一份自己的RxJava框架啦

RxJava是什么,在这里就不多做赘述了,如果不太懂,请出门google
简单提一下它的优点:
1. 链式调用—不再出现一缕缕的callback,实现代码整洁和良好可读
2. 线程调度—简单一行代码,实现不同函数运行在不同线程
3. 各种操作符-,链式转换-保持链式结构的同时,在传递过程中对数据进行转换,且转换安装顺序

Tks for OSTCB,基于此框架设计思路进行延伸

实现策略

考虑到一些场景的易读性,本文在描述中混淆了一下概念:
消费者—观察者—事件的消费者
生产者—被观察者—事件的产生者

  1. 链式调用实现原理: 观察者模式
    1.1 控制器 持有 1个生产者 和 多个消费者
    1.2 调用生产者的生产函数,并将多个消费者实例注入其中
  2. 线程调度的原理: 代理模式。
    2.1 所有类的成员函数的调用都不是直接由对应对象实例调用,而是由代理类去调用
    2.2 通用的总代理类,实现线程调度
  3. 操作符的原理: 适配器模式(装饰器 or 责任链模式)
    3.1 数据结构链式结构的头插法,实现责任链模式
    3.2 适配器模式,实现 endwith || startWith

实践概况

!!! 先放大招,全局UML图

这里写图片描述

实现步骤

注意

  • 线程操作,还未确定如何跟我们自己的嫁接
  • 混淆,里边有反射,混淆还未处理
-keep class * extends java.lang.annotation.Annotation { *; }
-keep enum xx.com.xx.invoker.entity.RunContextType{*;}


-keep class * implements xx.com.xx.observer.OnObserver { *; }
-keep class * implements xx.com.xx.observerable.OnPublisher { *; }
-keep class * implements xx.com.xx.action.Func1 { *; }
-keep class * implements xx.com.xx.action.Function { *; }
  • 泛型存在问题,会影响中间变换操作

优化1:泛型存在问题,会影响中间变换操作

  • 变换类例如map时,返回的链式对象 Pushliser改为新类型的值
    • 由于 链式操作的return this,导致Pushliser<0>不能直接返回,我们需要借助适配器PublisherConvert 将 O 转换为 T
public interface IPublisher<T> {
...
// 添加 事件的消费者---观察者
   public <O> IPublisher<O> change(Func1<T, O> change, Change changeProxy);
   public <O> IPublisher<O> map(Func1<T, O> map)
...
}


/**
 * 类描述:
 * Publisher<T> 转换为 Publisher<O>
 * Created by yhf on 2016/12/21.
 */
public final class PublisherConvert<T,O> extends Publisher<O> {

    Publisher<T> source;


    public PublisherConvert(Publisher<T> source){
        this.source = source;

        onObserver = source.getOnObserver();
        changeHead = source.getChangeHead();
        changeLast = source.getChangeLast();
        onPublisher = source.getOnPublisher();
        mapProxy = source.getMapProxy();
        filterProxy = source.getFilterProxy();
        data = source.getData();
        isInit = source.isInit();

    }

}

public class Publisher<T> implements IPublisher<T> {
...
    protected OnObserver onObserver;
    protected Change changeHead;
    protected Change changeLast;
    protected OnPublisher onPublisher;
    protected MapProxy mapProxy;
    protected FilterProxy filterProxy;
    protected DataPack data;
    protected boolean isInit = true;


    @Override
    public <O> IPublisher<O> map(Func1<T, O> maped) {
        Change<T,O> mapChange = new MapChange<T,O>();
        change(maped,mapChange);
        return new <O> PublisherConvert<T,O>(this);
    }

    @Override
    public <O> IPublisher<O> change(Func1<T, O> change, Change changeProxy) {
        changeProxy.setChangeImpl(change);
        changeLast.setPreChange(changeProxy);
        changeLast = changeProxy;
        return new <O> PublisherConvert<T,O>(this);
    }
...
}
  • 参考Rxjava,使用 ? super xx
public interface OnPublisher<T> {
    public void call(OnObserver<? super T> observer);
}

public interface IPublisher<T> {
...
// 添加 事件的消费者---观察者
    public IPublisher<T> bind(OnObserver<? super T> observer);
    public IPublisher<T> bind(Action1<? super T> action1);
...
}

优化2: Change< I, O >类操作支持 RunContextType

我们可以看到Change中是直接调用了changeImpl.call(),因此 change操作总是在当前线程运行,如果想要支持线程调度,则

  • 需要 func1的线程代理对象,调用Invoker

    • ???如何在线程中,拿到返回值,需要搞定Invoker的返回值
  • Change的setChangeImpl(Func1 changeImpl)将changeImpl封装为代理对象
import java.lang.reflect.Method;
import java.util.concurrent.Future;

/**
 * 【action操作的】 的代理
 * 使每个目标方法通过我们的调度器Invoker调用,而不是直接被调用,OnObserver和OnPublisher必须被代理
 * 从而,实现 线程调度
 * 否则用户就可以直接调用,没法实现线程调度
 *  - 实现 消费者的接口---代理模式的基本需求
 *  - 持有 实际的 <font color= red>消费者们 </font> 实例
 *  - 重写 消费者接口的对应函数
 *    注意1:不能直接调用被代理对象的成员函数,而是交由 线程调度器统一处理
 *    注意2:遍历消费者们,代理类是所有消费者的代理,保证生产者.call(消费者)中调用消费者时,所有函数都会被执行
 *  - 消费者容器的增删查
 * Created by yhf on 16/12/18.
 */
public class Func1Proxy implements Func1{

    protected Func1 changeImpl; // 转换代理 实例
    private Invoker invoker;

    private Future future;

    public Func1Proxy(Func1 func1) {
        this.changeImpl = func1;
    }

    public Future getFuture() {
        return future;
    }

    @Override
    public Object call(Object o) {
        String MethodName = "call";
        Class parType = OnObserver.class;
        if (invoker == null)
            invoker = Invoker.getInstance();
        try {
            Method method = changeImpl.getClass().getMethod(MethodName,parType);
            //1. 获取 method对应注解
            //2. 在对应线程上,调用onPublisher.method(observer)
            future = invoker.invoke(method,changeImpl, o);
            return future.get();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

public abstract class Change<I,O> implements OnObserver<I>,IObserverProxy<O> {
...
    public void setChangeImpl(Func1 changeImpl) {
        this.changeImpl = new Func1Proxy(changeImpl);
    }
...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值