在日常事务中,我们常常依次做如下操作: 排队取得一个单号; 根据这个单号享有一个操作; 为当前的这个操作买单.
在Android中也一样,为了不阻塞主线程,我们把所有耗时行为都封装为多个线程,有的时候需要先运行线程A,根据得到的结果再运行线程B, 再根据B的结果运行线程C. 时序图如下:
如果我们在ThreadA结束前的代码中插入ThreadB.start, 再ThreadB的结束前的代码中插入ThreadC.start. 那这样的代码很难读,从整体上看也像棉花糖一样无比壮大....
其实在android中有比较优雅的简单的方式处理这个。如下以两个Thread为例子展开演进:
conditionVariableForConnection = new ConditionVariable(); app.method01(param1, param2, new callback01() { @Override public void method4Callback01(Object result01) { conditionVariableForRequestSession.open(); ... } };
conditionVariableForRequestSession.block(SESSION_WAIT_TIME_MS); if(getSession()) { app.method02(param01,param02,callback02(){}); } ...
ExecutorService executorService = Executors.newSingleThreadExecutor(); Callable<String> callback01 = new Callable<String>() { @Override public String call() throws Exception { return HttpHelper.getURLRequestHeadInfo("url01"); } }; Future<String> future01 = executorService.submit(callback01); Callable<String> callback02 = new Callable<String>() { @Override public String call() throws Exception { return HttpHelper.getURLRequestHeadInfo("url02"); } }; Future<String> future02 = executorService.submit(callback02); if(HttpHelper.isSessionAvaiable(future01.get()) && HttpHelper.isSessionAvaiable(future02.get()) ) { ... }
总结:
上述两种方式都是用同步的方式进行着异步的处理,代码的直观性和可移植性成倍增加
ConditionVariable方式主要用来协同多个开发员之间的接口或与老系统的交接。随着交互接口的增多需要多次使用ConditionVariable,但是他的可读性比我们棉花糖式的代码有了直接改观;
ExecutorService方式在上下文数据交互(根据前一线程结果来运行新的线程)方面很优雅,整体效率也更高点