让一个类NotifyTaskRunner
在一个线程中运行一个任务,当任务完成时,它将使用 Handler 发布一个 Runnable,在其中它将调用DataPrepareCallback::onComplete(T)
Handler 所在的任何线程。
class NotifyTaskRunner {
final private Handler handler; //new Handler(Looper.getMainLooper());
interface DataPrepareCallback<R> {
void onComplete(R result);
}
NotifyTaskRunner(@Nullable Handler handler) {
this.handler = handler;
}
<R> void asyncRun(Executor executor, final Callable<R> callable, final DataPrepareCallback<R> callback) {
final Handler theHandler = this.handler;
executor.execute(new Runnable() {
@Override
public void run() {
R result = null;
try {
result = callable.call();
} catch (Exception e) {}
if (theHandler != null) {
final R finalResult = result;
System.out.println("+++ before handler.post, result:"+result+", theHandler:"+theHandler);
handler.post(new Runnable() {
@Override
public void run() {
System.out.println("+++ in handler.post.run(), thread: "+Thread.currentThread().getId()+", call callback.onComplete(finalResult), ret:" + finalResult);
callback.onComplete(finalResult); //<=== never get called ???
}
});
} else {
System.out.println("+++ no handler, thread: "+Thread.currentThread().getId(), ret:" + result);
callback.onComplete(result);
}
}
});
}
}
问题出在测试中,当 Handler 为 时Handler(Looper.getMainLooper())
,Runnable::run()
从未调用过,也没有DataPrepareCallback::onComplete()
.
当不通过测试时,被调用Handler
的测试工作正常。DataPrepareCallback::onComplete()
@Test
public void test_Handler() throws Exception {
ExecutorService executorPool = Executors.newFixedThreadPool(2);
final long currThreadId = Thread.currentThread().getId();
final long[] taskThreadId2 = {-1};
final CountDownLatch latch2 = new CountDownLatch(1);
Handler looper = new Handler(Looper.getMainLooper());
Callable<Bitmap> task = new Callable<Bitmap>(){
@Override
public Bitmap call() throws Exception {
return null;
}
};
NotifyTaskRunner taskRunner2 = new NotifyTaskRunner(looper);
taskRunner2.asyncRun(executorPool, task,
new DataPrepareCallback<Bitmap>() {
@Override
public void onComplete(Bitmap bmp) {
latch2.countDown();
taskThreadId2[0] = Thread.currentThread().getId();
System.out.println("+++ 222 asyncFetch.onComplete(bmp), taskThreadId2[0]:"+taskThreadId2[0]);
}
}
);
// shadowOf(getMainLooper()).idle();
// ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); //,=== these two do not help
boolean b = latch2.await(10, TimeUnit.SECONDS);
System.out.println("+++ latch2 count == 0 :"+b+", taskThreadId2[0]:"+taskThreadId2[0]);
}
打印出来的有:
......
+++ before handler.post, result:null, theHandler:Handler (android.os.Handler) {282854d8}
+++ latch2 count == 0 :false, taskThreadId2[0]:-1
如何测试Runnable'run(),验证它是否在Handler的线程上等等?