Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 保证回调始终异步执行的最佳方法是什么?_Java_Android_Concurrency - Fatal编程技术网

Java 保证回调始终异步执行的最佳方法是什么?

Java 保证回调始终异步执行的最佳方法是什么?,java,android,concurrency,Java,Android,Concurrency,我正在开发一个Android应用程序,它必须发出服务器请求,然后在请求完成后执行操作。下面是一些伪代码来帮助解释这种情况: makeRequest(new SomeTask{ onDone() { // Do actionB with queue } }); // Do actionA with queue. Must be execute first!! 以下是伪代码中makeRequest的实现: makeRequest(SomeTask task) {

我正在开发一个Android应用程序,它必须发出服务器请求,然后在请求完成后执行操作。下面是一些伪代码来帮助解释这种情况:

makeRequest(new SomeTask{
    onDone() {
        // Do actionB with queue
    }
});

// Do actionA with queue.  Must be execute first!!
以下是伪代码中
makeRequest
的实现:

makeRequest(SomeTask task) {
    if(canDoOptimization) { // if true, don't need to make request

        // It's a bad idea to execute this immediately.
        // Wish I could wait until the current thread of execution was done...
        task.onDone();
        return;
    }

    asyncTask = new AsyncTask<SomeTask, Void, Void>() {
        doInBackground(SomeTask... task) {
            // Make server request...

            task.onDone();
        }
    }
    asyncTask.execute(task);
}
makeRequest(SomeTask任务){
if(canDoOptimization){//如果为true,则不需要发出请求
//立即执行这是个坏主意。
//希望我能等到当前的执行线程完成。。。
task.onDone();
返回;
}
asyncTask=新建asyncTask(){
doInBackground(某些任务…任务){
//发出服务器请求。。。
task.onDone();
}
}
asyncTask.execute(任务);
}
通常
actionA
发生在
actionB
之前,但在我们可以避免网络请求的情况下,会立即调用
SomeTask.execute
。这会导致
actionB
actionA
之前发生,这是不好的。我能保证这不会发生吗

我在javascript中多次遇到这种情况。在这种情况下,我会将
SomeTask.execute
调用包装为
setTimeout
setImmediate
,以保持正确的异步语义

为清楚起见,下面是JavaScript中相同错误的一个示例:


知道我应该在Java/Android中做什么吗?

欢迎来到同步世界。互斥对象或锁对象通常用于此目的


您的B任务应该在互斥锁上等待,该互斥锁将在任务完成时由任务A发出信号。这将确保任务在B之前完成的正确执行顺序。

始终将
task.onDone()
放在
AsyncTask
中,即使它不必发出请求

makeRequest(SomeTask task) {

    asyncTask = new AsyncTask<SomeTask, Void, Void>() {
        void doInBackground(SomeTask... task) {

            if(canDoOptimization) { // if true, don't need to make request

                // It's a bad idea to execute this immediately.
                // Wish I could wait until the current thread of was done...
                task.onDone();
                return;
            } else {
                // Make server request...

                task.onDone();
            }
        }
    }
    asyncTask.execute(task);
}
makeRequest(SomeTask任务){
asyncTask=新建asyncTask(){
void doInBackground(SomeTask…task){
if(canDoOptimization){//如果为true,则不需要发出请求
//立即执行这是个坏主意。
//希望我能等到当前的线程完成。。。
task.onDone();
返回;
}否则{
//发出服务器请求。。。
task.onDone();
}
}
}
asyncTask.execute(任务);
}

为什么你不能改变事情的顺序

// Do actionA with queue.  Must be execute first!!

makeRequest(new SomeTask{
onDone() {
    // Do actionB with queue
});
如果actionA也是异步的,并且是在单独的AsyncTask上执行的,那么可以在actionA的AsyncTasks的onPostExecute()方法上调用makeRequest(…)

顺便说一句,自从Android蜂巢版本以来,异步任务在同一个线程上运行,这意味着如果您有多个任务,它们可以相互阻止。 通过指定AsyncTsak应在线程池中运行,可以解决此问题:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
  asyncTask.execute();
}

为什么不能在makeRequest之前调用操作呢?这是一种可能性,但需要进行重大重构。另外,我还希望有一个通用的解决方案,这样我就不用担心这个问题了。设置超时似乎是一个非常棘手的解决方案,在Java中可能是这样。但在JS中,我觉得这是
setTimeout
的标准用例。Node.js提供了一个更优化的版本,名为
process.nextTick
,这是非常常见的,这非常有意义。不幸的是,我过度简化了我的例子。
canDoOptimization
检查和实际网络调用发生在不同的位置。
SomeTask
对象被传递了很多次。也许我可以把
task.onDone()
调用包装成一个虚拟的
AsyncTask
?一个虚拟的AsyncTask值得一试。事实上,我不是安卓专家,我只是在暗中摸索:)