RxJava是什么,在这里就不多做赘述了,如果不太懂,请出门google
简单提一下它的优点:
1. 链式调用—不再出现一缕缕的callback,实现代码整洁和良好可读
2. 线程调度—简单一行代码,实现不同函数运行在不同线程
3. 各种操作符-,链式转换-保持链式结构的同时,在传递过程中对数据进行转换,且转换安装顺序Tks for OSTCB,基于此框架设计思路进行延伸
实现策略
考虑到一些场景的易读性,本文在描述中混淆了一下概念:
消费者—观察者—事件的消费者
生产者—被观察者—事件的产生者
- 链式调用实现原理: 观察者模式
1.1 控制器 持有 1个生产者 和 多个消费者
1.2 调用生产者的生产函数,并将多个消费者实例注入其中 - 线程调度的原理: 代理模式。
2.1 所有类的成员函数的调用都不是直接由对应对象实例调用,而是由代理类去调用
2.2 通用的总代理类,实现线程调度 - 操作符的原理: 适配器模式(装饰器 or 责任链模式)
3.1 数据结构链式结构的头插法,实现责任链模式
3.2 适配器模式,实现 endwith || startWith
实践概况
实现步骤
- (4.6.22.1)来吧,是时候撸一份自己的RxJava框架啦:观察者模式实现链式调用
- (4.6.22.2)来吧,是时候撸一份自己的RxJava框架啦:代理模式实现线程调度
- (4.6.22.4)来吧,是时候撸一份自己的RxJava框架啦:残缺消费者的实现
- (4.6.22.5)来吧,是时候撸一份自己的RxJava框架啦:强撸为eventbus
注意
- 线程操作,还未确定如何跟我们自己的嫁接
- 混淆,里边有反射,混淆还未处理
-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);
}
...
}