【问题标题】:Can I chain async task sequentially (starting one after the previous asynctask completes)我可以按顺序链接异步任务吗(在前一个异步任务完成后开始一个)
【发布时间】:2011-11-21 14:40:34
【问题描述】:

每次我执行httpRequest 时,在代码执行期间屏幕似乎会被锁定几秒钟。因此,我使用AsyncTask 在单独的线程中完成我所有的httpRequest 内容,同时设置ProgressDialog,以便用户知道发生了什么事。

我最近遇到了以下情况:我的httpRequest 之一的输入依赖于先前httpRequest (+parse) 操作的结果。我不能只按顺序放置两个AsyncTasks,因为Android 会将它们放在两个线程中并在第一个线程未完成的情况下启动第二个线程。如果没有适当的输入(第一个 httpRequest 的结果),我的第二个 httpRequest 将使应用程序崩溃。

有没有办法我可以输入 wait() 来强制第二个 AsyncTask 在第一个完成之前不要开始?

【问题讨论】:

    标签: java android android-asynctask


    【解决方案1】:

    前几天我也遇到了同样的情况。 我以这种方式解决了它: 将活动的引用传递给异步类的构造函数并在后台执行 do 函数。现在在执行后函数中,从异步类调用你的活动的公共方法以再次执行任务......或者试试这个:

                if (asynclass.getStatus() == android.os.AsyncTask.Status.PENDING) {
                    asynclass.execute();
                } else if (RF.getStatus() == android.os.AsyncTask.Status.FINISHED) {
                    asynclass = new asyncclass();
                    asynclass.execute();
                } else {
                    Toast.maketoast(this, "Plz wait", 1).show();
                }
    

    干杯

    【讨论】:

    • +1 是的,同意@Await,我们可以通过getStatus()方法获取任意AsyncTask的状态。
    • 我考虑过按照您和@nik 的建议,在 postExcute 函数中调用第二个 asynctask,但是在另一个 ansyctask 中调用 asynctask 是一种不好的做法吗?
    【解决方案2】:

    所以我认为(不确定),您需要在后执行方法上调用第二个 asyncTask

    protected void onPostExecute(final Void unused) {
                if (this.dialog.isShowing()) {
                    this.dialog.dismiss();
                         new secTask().execute();
                }}
    

    【讨论】:

      【解决方案3】:

      是的,你可以。但这只能在onProgressUpdate()onPostExecute() 中使用。尝试这样做:

      private class Task1 extends AsyncTask<Void, Void, Void> {
      ...
      ...
          protected void onPostExecute(Void unused) { 
              dialog1.dismiss();
              new Task2().execute();
          }
      
      }
      

      同样,您必须将new Task3().execute(); 放入Task2 的AsyncTaskonPostExecute() 方法中

      不要在主代码中这样称呼它们。如果你这样做,那么它们将一起运行:

      // This is wrong
      new Task1().execute();
      new Task2().execute();
      new Task3().execute();
      

      参考:AsyncTask

      【讨论】:

        【解决方案4】:

        使用executOnExecutor方法怎么样:

        public void runTasks() {
        
                AsyncTask<Void,Void,Void> aTask = myTask();
                AsyncTask<Void,Void,Integer> aTask1 = myTask1();
                AsyncTask<Void,Void,Void> aTask2 = myTask2();
        
                aTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
                aTask1.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
                aTask2.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
        
            }
        

        【讨论】:

        • 但是这样你将无法创建某种流控制。哦,我的错,你仍然可以在 onPreExecute 回调中做到这一点。
        【解决方案5】:

        偶然发现这个线程正在寻找比我目前使用的更好的解决方案,但它似乎仍然是最好的......

        我所做的是在我的每个异步任务的构造函数中传递一个可运行对象。

        无论是在后期执行中还是在后台执行结束时,我都会启动我的下一个任务,如果我有一个通过执行可运行的任务。

         if(doOnPostExec != null)
                doOnPostExec.run();
        

        通过这种方式,我可以通过我传递的可运行文件来更改异步任务的顺序,从而保持代码的灵活性,如果我没有传递任何可运行文件,它们会正常完成。可运行文件只包含一行调用下一个异步任务。

        我只是不喜欢制作所有这些可运行文件。希望在 vb.net 中存在类似的东西来链接代表。

        【讨论】:

          【解决方案6】:

          我以前遇到过这个问题。我所做的是使用回调接口类并在 onPostExecute() 方法中调用其方法。这样你就可以从回调方法中调用另一个 AsyncTask。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多