前言:上一篇架构了Rx的基础,这次我们来动手写一下调度器,对应RxJava的Schedule,个人认为对于android来说,调度器的加入是重中之重。对于Android来说异步处理一直是在编码上是一个扰乱代码结构的因素,Handler的编写常常让人头疼。
调度器内容我是直接没看Rxjava的实现,以前也“山寨“过EventBus,XUtils觉得用注解比较美观方便,所以把SubscribeOn换成了注解看上去更简洁一点。还可以单独控制每个目标方法的运行线程。
1.首先是抽象出一个直接调用的Abstarct类。
public abstract class IInvokeDirect<T>{
protected T proxy;
public void setProxy(T t){
proxy = t;
}
public abstract <V> V invoke(String methodname,Object... pars);
}
T代表的是调用实体类的类型由于一个实体类中可以有多个目标方法,所以以methodname作为判断依据。
public class PublisherInvoker extends IInvokeDirect<OnPublisher>{
@Override
public <V> V invoke(String methodname, Object... pars) {
proxy.call((OnObserver) pars[0]);
return null;
}
}
OnPublish的实现。无返回值有一个参数
OnObserver的实现内含三个目标方法public class ObserverInvoker extends IInvokeDirect<OnObserver>{ @Override public <V> V invoke(String methodname, Object... pars) { V res = null; switch (methodname){ case "onFinished": proxy.onFinished(); break; case "onSuccess": proxy.onSuccess(pars[0]); break; case "onError": proxy.onError((Throwable) pars[0]); break; } return res; } }
Func1的实现这是单参数+返回值调用的抽象public class Function1Invoker<I,O> extends IInvokeDirect<Func1<I,O>> { @Override public <O> O invoke(String methodname, Object... pars) { O ret = (O) proxy.call((I) pars[0]); return ret; } }
2.讲完直接调用接下来就是调度器主体
首先是Runnable实现类,这是必要的。封装了方法调用和掩饰
public class ProxyEntity implements Runnable{ private Method method; private Object object; private Object[] args; private Object ret; private int delay = 0; public ProxyEntity(Method method, Object object, Object... args) { this.method = method; this.object = object; this.args = args; } public void setDelay(int delay) { this.delay = delay; } @Override public void run() { if (delay!=0){ try { Thread.currentThread().sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } } Invoker.invoke_direct(method,object,args); } }
(1).invoke_direct分发器 分发各种直接调用。
通过instanceof分发调用实体public static <T> T invoke_direct(Method method, Object object, Object... values){ String name = method.getName(); IInvokeDirect invoke = null; if (object instanceof OnObserver){ invoke = new ObserverInvoker(); invoke.setProxy(object); }else if (object instanceof OnPublisher){ invoke = new PublisherInvoker(); invoke.setProxy(object); }else if (object instanceof Func1){ invoke = new Function1Invoker(); invoke.setProxy(object); } if (invoke == null) return null; Object ret = invoke.<T>invoke(name,values); if (ret == null) return null; return (T) ret; }
(2).调度的种类 分装在emun中
可以看到种类还是很多的,下面一个个来看 有点多public enum RunContextType { MainThread, MainLoop, NewThread, NewHandlerThread, CurrentThread, CurrentLoop, IO, Calculate, Dynamic, Custome; }
1).CurrentThread在当前线程调用,注意这里加入了delay
2).CurrentLoop当前线程的消息队列private <T> T invoke_current_thread(Method method, Object object,int delay,Object... values) { if (delay!=0) { try { Thread.currentThread().sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } } return invoke_direct(method, object, values); }
注意当前线程如果不是hanlerthread则会抛出RunTime异常private void invoke_current_loop(Method method, Object object,int delay, Object... values) { Looper looper = Looper.myLooper(); if (looper == null) throw new RuntimeException(Thread.currentThread().getName()+"不是HandlerThread"); Handler handler = new Handler(looper); ProxyEntity entity = new ProxyEntity(method,object,values); if (delay == 0) handler.post(entity); else handler.postDelayed(entity,delay); }
3).MainThread主线程非常重要的一个
4).MainLoop主线程消息队列,和MainThread其实有些不同,体现在调用时机上,MainLoop在MainThread的调用时机靠后。private void invoke_main_thread(Method method, Object object,int delay,Object... values) { Looper mianLoop = Looper.getMainLooper(); ProxyEntity entity = new ProxyEntity(method,object,values); if (Looper.myLooper() != Looper.getMainLooper()){ invoke_main_loop(method, object,delay,values); }else { invoke_current_thread(method, object, delay, values); } }
5).NewThread,新线程。private void invoke_main_loop(Method method, Object object,int delay,Object... values) { ProxyEntity entity = new ProxyEntity(method,object,values); if (delay == 0) mainHandler.post(entity); else mainHandler.postDelayed(entity,delay); }
6).IO,IO专用线程,是一个单队列的线程池,这个还有待商榷,具体实现继承在我的框架里private void invoke_new_thread(Method method, Object object,int delay,Object... values) { ProxyEntity entity = new ProxyEntity(method,object,values); entity.setDelay(delay); new Thread(entity).start(); }
7).Calculate,计算专用线程,是一个并发数为CPU核心数的线程池,适合密集型计算private void invoke_io(Method method, Object object,int delay,Object... values) { ProxyEntity entity = new ProxyEntity(method,object,values); entity.setDelay(delay); MySigleThreadQueue.AddTask(entity); }
8).NewHandlerThread,新的HandlerThreadprivate void invoke_calculate(Method method, Object object,int delay,Object... values) { ProxyEntity entity = new ProxyEntity(method,object,values); entity.setDelay(delay); MyWorkThreadQueue.AddTask(entity); }
3.调度方法的分发器,根据方法体上的注解分发private void invoke_new_handler_thread(Method method, Object object,int delay,Object... values) { ProxyEntity entity = new ProxyEntity(method,object,values); HandlerThread thread = new HandlerThread(object.getClass().getName()+method.getName()); thread.start(); Handler handler = new Handler(thread.getLooper()); if (delay == 0) handler.post(entity); else handler.postDelayed(entity,delay); }
可以看到如果不指定运行的线程的话默认就是CurrentThread即直接调用。public void invoke(Method method, Object object, Object... values){ RunContext runContext = method.getAnnotation(RunContext.class); RunContextType type; int delay = 0; if (runContext == null) type = RunContextType.CurrentThread; else type = runContext.value(); Delay delayAnno = method.getAnnotation(Delay.class); if (delayAnno!=null) delay = delayAnno.value(); switch (type){ case CurrentThread: invoke_current_thread(method,object,delay,values); break; case CurrentLoop: invoke_current_loop(method,object,delay,values); break; case NewThread: invoke_new_thread(method,object,delay,values); break; case MainThread: invoke_main_thread(method,object,delay,values); break; case MainLoop: invoke_main_loop(method,object,delay,values); break; case Calculate: invoke_calculate(method,object,delay,values); break; case IO: invoke_io(method,object,delay,values); break; case NewHandlerThread: invoke_new_handler_thread(method,object,delay,values); break; case Dynamic: invoke_dynamic(method, object, values); break; } }
Invoke_Dynamic是为以后的变换方法体做准备的,因为注解的指定是编译时确定的,不是变量而是常量。4.最后为了使每个目标方法通过我们的调度器Invoker调用,而不是直接被调用,OnObserver和OnPublisher必须被代理,否则用户就直接调用了。public class ObserverProxy<T> implements OnObserver<T>,IObserverProxy<T>{ private Vector<OnObserver<T>> observers; private Invoker invoker; public ObserverProxy() { observers = new Vector<OnObserver<T>>(); invoker = Invoker.getInstance(); } @Override public void onSuccess(T t) { String methodName = "onSuccess"; for (OnObserver<T> observer:observers){ try { Method method = observer.getClass().getMethod(methodName,Object.class); invoker.invoke(method,observer,t); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Override public void onError(Throwable throwable) { String methodName = "onError"; Class type = Throwable.class; for (OnObserver<T> observer:observers){ try { Method method = observer.getClass().getMethod(methodName,type); invoker.invoke(method,observer,throwable); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Override public void onFinished() { String methodName = "onFinished"; for (OnObserver<T> observer:observers){ try { Method method = observer.getClass().getMethod(methodName); invoker.invoke(method,observer,null); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } @Override public void addObserver(OnObserver<T> observer) { observers.add(observer); } @Override public void rmObserver(OnObserver<T> observer) { observers.remove(observer); } @Override public void clear() { observers.clear(); } @Override public Vector<OnObserver<T>> getObservers() { return observers; } }
public class OnPublisherProxy<T> implements OnPublisher<T>{ private OnPublisher<T> onPublisher; private Invoker invoker; public OnPublisherProxy(OnPublisher<T> onPublisher) { this.onPublisher = onPublisher; } @Override public void call(OnObserver<T> observer) { String MethodName = "call"; Class parType = OnObserver.class; if (invoker == null) invoker = Invoker.getInstance(); try { Method method = onPublisher.getClass().getMethod(MethodName,parType); invoker.invoke(method,onPublisher, observer); } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
用以上两个代理类代理原Publisher中的observers和onpubliser忘了注解的实体:至此调度器部分就基本结束了。让我们使用一下试试吧。@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RunContext { RunContextType value()default RunContextType.CurrentThread; }
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Delay { int value()default 0; }
Publisher.<String>getInstance() .create(new OnPublisher<String>() { @Delay(3*1000) @RunContext(RunContextType.IO) @Override public void call(OnObserver<String> observer) { String res = null; res = httpmodel.dohttp(); if (res!=null) observer.onSuccess(res); else observer.onError(new Throwable("error")); } }) .bind(new OnObserver<String>() { @RunContext(RunContextType.MainThread) @Override public void onSuccess(String s) { resTextView.setText(s); } @RunContext(RunContextType.MainThread) @Override public void onError(Throwable throwable) { Toast.makeText(MainActivity.this,throwable.getMessage(),Toast.LENGTH_LONG).show(); } @Override public void onFinished() { } }) .post();
在IO线程中发布了从网络回去一段字符串,在UI线程中订阅更新UI,是不是看着很清爽?如果你是用的是AS的话,结合lambda表达式看的更清爽。完全没有原来Handler的困扰。预告:第三集是变换,即Rxjava中的操作符