简体   繁体   English

Java保证回调订单执行

[英]Java guarantee callback order execution

How do I guarantee the execution of a certain code after another on Android? 我如何保证在Android上执行某个代码?

I have an asynchronous callback, done, which gets executed in another thread after a Parse api query finishes, here is the code 我有一个异步回调,完成,在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 -----'
}

So I tried this, but didn't work, it blocks when tries to acquire the second time the semaphore 所以我尝试了这个,但没有工作,它试图获得第二次信号量时阻止

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();
    }
}

Is it because semaphore is released in a thread that didn't acquire it? 是因为信号量是在一个没有获得信号的线程中发布的吗? How to fix this solution? 如何解决这个问题?

However, I also tried this dummy way of solving the problem 但是,我也尝试过这种解决问题的虚拟方法

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);
}

But it didn't work, it blocks inside the loop, and callback does not get executed. 但它不起作用,它在循环内部阻塞,并且回调不会被执行。 By removing the loop in this one the callback gets executed, so the problem must be related with the loop 通过删除此循环中的循环,将执行回调,因此问题必须与循环相关

I usually do it with CountDownLatch . 我通常使用CountDownLatch来做。 As far as I could check, it exists in Android API too ( here ), so you can use it: 据我所知,它也存在于Android API中( 这里 ),所以你可以使用它:

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);
}

There is only one caveat here: you need to make sure that the taskFinishedLatch.countDown(); 这里只有一个警告:你需要确保taskFinishedLatch.countDown(); is being invoked. 被调用。 This is why I added the try {...} finally {...} blocks. 这就是我添加try {...} finally {...}块的原因。

In this case this is not enough though. 在这种情况下,这还不够。 You need to handle the case when the query does not call the done callback. 当查询未调用done回调时,您需要处理该情况。 Ie is there an error callback? 即是否有error回调? You can use time timeouts, like taskFinishedLatch.await(5, TimeUnit.SECONDS) , but that makes the behavior a bit fuzzy. 您可以使用taskFinishedLatch.await(5, TimeUnit.SECONDS)等时间超时,但这会使行为有点模糊。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM