Java保证回调订单执行
问题描述:
如何保证在Android上接连执行某个代码?Java保证回调订单执行
我有一个异步回调,完成,这被在另一个线程解析API查询完成后执行,这里是
Init() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable");
query.getInBackground("ObjectID", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
// [ ... some code ... ] <----------.
} // |
}); // |
// I'd like this is executed after this -----'
}
所以,我想这个代码,但没有奏效,它会阻止时尝试第二次获取信号量
private final Semaphore available = new Semaphore(1, true);
Init() {
try {
available.acquire();
ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable");
query.getInBackground("ObjectID", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
// [ ... code ... ]
available.release();
}
});
available.acquire(); // waits till release
available.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
是否因为信号在未获取它的线程中释放?如何解决这个问题?
不过,我也试图解决这个问题
private static volatile Boolean available = false;
Init() {
available = false;
ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable");
query.getInBackground("ObjectID", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
// [ ... some code ... ]
available = true;
}
});
while (available == false);
}
的这种虚拟方式,但它没有工作循环内,它块,回调没有得到执行。通过删除这一个循环回调得到执行,所以问题必须与循环有关
答
我通常使用CountDownLatch
来完成。至于我可以检查,它存在于Android的API太(here),所以你可以使用它:
Init() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable");
final taskFinishedLatch = new CountDownLatch(1);
query.getInBackground("ObjectID", new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
try {
// [ ... some code ... ]
} finally {
taskFinishedLatch.countDown();
}
} // |
}); // |
taskFinishedLatch.await();
// alternatively, you can use timeouts, e.g.
// taskFinishedLatch.await(5, TimeUnit.SECONDS);
}
这里有只有一个警告:你需要确保taskFinishedLatch.countDown();
被调用。这就是为什么我添加了try {...} finally {...}
块的原因。
在这种情况下,这是不够的。当查询不调用done
回调时,您需要处理该案例。即是否有error
回调?您可以使用时间超时,如taskFinishedLatch.await(5, TimeUnit.SECONDS)
,但这会使行为有点模糊。
如果你想要一个特定的订单你为什么要使用异步? – EJP