如何保证 Android 上特定代码的执行?
我有一个异步回调,done,它在 Parse 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 {...}
block 。
在这种情况下,这还不够。您需要处理查询未调用 done
回调的情况。 IE。有error
回调吗?您可以使用时间超时,例如 taskFinishedLatch.await(5, TimeUnit.SECONDS)
,但这会使行为有点模糊。
关于Java保证回调顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43837737/