在日常事务中,我们常常依次做如下操作: 排队取得一个单号; 根据这个单号享有一个操作; 为当前的这个操作买单.
在Android中也一样,为了不阻塞主线程,我们把所有耗时行为都封装为多个线程,有的时候需要先运行线程A,根据得到的结果再运行线程B, 再根据B的结果运行线程C. 时序图如下:
如果我们在ThreadA结束前的代码中插入ThreadB.start, 再ThreadB的结束前的代码中插入ThreadC.start. 那这样的代码很难读,从整体上看也像棉花糖一样无比壮大....
其实在android中有比较优雅的简单的方式处理这个。如下以两个Thread为例子展开演进:
- ConditionVariable方式
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 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方式在上下文数据交互(根据前一线程结果来运行新的线程)方面很优雅,整体效率也更高点