【问题标题】:AsyncTask, Threads in AndroidAsyncTask,Android 中的线程
【发布时间】:2016-04-18 09:27:46
【问题描述】:

我有两个执行 SOAP 调用的函数和另一个从两个 SOAP 调用中生成列表的函数。我正在考虑如何等待两个 SOAP 调用完成并运行第三个函数。

Function A = SOAP (independent of B)
Function B = SOAP (independent of A)
Function C = Making a List from A & B (dependent on both A & B)
Function D = displaying using List from C

我当前的解决方案是将 A 放在异步任务中,将 B 放在 A 的 onpostexecute 中,将 C 放在 B 的 onpostexecute 中,这不起作用。我尝试在每个函数的开头和结尾放置两个日志。它在 A 完成它的两个日志之前就开始记录 B 的函数,这导致 C 混乱。

我正在考虑将 A 和 B 放在单独的线程中,并在完成后加入它们。然后将 C 放在异步任务或另一个线程中。但我担心这会导致 D 出现问题(显示来自 C 的列表),因为使用我当前的异步任务解决方案会出现赛车问题。

【问题讨论】:

    标签: java android multithreading soap android-asynctask


    【解决方案1】:

    嗯,这是一个逻辑顺序和并发性的问题。试试这个方法:

    public void process() {
            Thread funcAThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    startFunctionA();
                }
            });
    
            Thread funcBThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    startFunctionB();
                }
            });
    
            try {
                funcAThread.start();
                funcBThread.start();
                funcAThread.join();
                funcBThread.join();
                startFunctionC();
                startFunctionD();
            } catch (InterruptedException e) {
                Log.getStackTraceString(e);
            }
        }
    

    注意:确保所有对 UI 视图 的调用(尤其是在函数 D 中)都在 UI 线程 内使用 Activity.runOnUiThread(Runnable runnable) 处理.

    注意 2: 如果 functionC 很耗时,您也可以从 Thread 中调用它,以使您的应用保持响应(这非常重要)。所以根据我上面的代码:

        try {
            funcAThread.start();
            funcBThread.start();
            funcAThread.join();
            funcBThread.join();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    startFunctionC();
                    //once completed, call UI thread for D !
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            startFunctionD();
                        }
                    });
                }
            }).start();
        } catch (InterruptedException e) {
            Log.getStackTraceString(e);
        }
    

    注意 3: 我不建议使用 AsyncTask。不是因为它不好(当然不是),而是因为它们适用于需要定义 beginning 的操作,即在 background 中使用常规 处理的长时间操作>更新在 UI 线程上执行,最后在主要的长操作完成后执行一些其他操作。 您可以使用一个 AsyncTask 来执行所有操作,但您会失去使用两个并发线程的优势,这些线程可以利用多核 CPU 并因此更快地处理您的数据/执行您的操作。此外,我相信在某些 Android 版本上,您一次只能使用一个 AsyncTask。检查此答案以获取更多信息:https://stackoverflow.com/a/4072832/3535408。所以你最好使用线程:更清晰、更简单、同样快速。

    【讨论】:

    • 不管怎样,AsyncTasks 可以并行运行。使用task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);。但是,这已锁定到更高的 Android 版本。
    • @Knossos 完全正确,这就是为什么我在我的 Note3 中包含一个链接,该链接提供了有关运行并行 AsynTasks 问题的许多详细信息;-)跨度>
    • 糟糕!错过了。抱歉!
    • 没问题。有趣的是,我遇到了这个 SO 帖子,因为一年前我遇到了同样的问题,因为我试图同时运行 5 个 AsyncTask。我讨厌 AsyncTask,我尽量不使用它们。只要您现在要做什么,具有基于可用内核数量的固定线程数的自定义托管 ThreadPool 就是要走的路;-)
    • 我的印象是 asyntasks 可以再次并行运行?如果是这样,那么可以运行多个异步任务,并且如果与倒计时锁存器一起使用,则可以全部同步?
    【解决方案2】:

    通过各自的AsyncTask 同时运行AB

    A & BonPostExecute 函数中,调用记录任务已运行的函数。

    在这个回调函数中,检查AB是否都完成,然后在另一个AsyncTask中运行C

    例子:

    在每个 AsyncTask 中:

    onPostExecute(Void result) {
        mCallback.onTaskCompleted(this.class);
    }
    

    在调用 AsyncTasks 的类中:

    onTaskCompleted(Class task) {
        if(task instanceof AsyncTaskA) mTaskA = true;
        else if(task instanceof AsyncTaskB) mTaskB = true;
    
        if(mTaskA && mTaskB) {
            runTaskC();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      相关资源
      最近更新 更多