从另一个AsyncTask doInBackground()启动AsyncTask

时间:2013-10-22 14:27:59

标签: android android-asynctask

我正在尝试从另一个 AsyncTask的 doInBackground() - 方法启动 AsyncTask ...

这甚至可能吗?如果是,我该如何实现?

LATER EDIT:

我的想法是,我启动了一个asynctask,它将从Tweeter获取状态......一切正常,直到这里......但是当我遇到一些特定的推文时,我需要用我服务器上的一些信息修改它们,这里我会进行另一次网络操作,因为我需要等到我从服务器获取信息后才会这样做:

GetContent getContentServiceAsyncTask = new GetContent(context);
try {
    tweetText = Uri.decode(getContentServiceAsyncTask.execute(
            URL_GET_CONTENT, jsonRequest).get());
} catch (InterruptedException e) {
    Log.e(TAG_DEBUG, "InterruptedException: ", e);
} catch (ExecutionException e) {
    Log.e(TAG_DEBUG, "ExecutionException: ", e);
}

这是从doInBackground()方法中已经启动的AsyncTask开始的......

我知道我可以在AsyncTask中添加方法,只需在doInBackground()方法中调用它们,但我需要在其他地方使用它们,我从onPostExecute启动这些AsyncTasks ...

如果你们认为有一个简单的解决办法,这不会影响我的表现,这将是伟大的......如果不是,我将制作一些静态方法,我将调用我需要的所有AsyncTasks (但这需要我修改我的很多代码)

7 个答案:

答案 0 :(得分:15)

AsyncTasks应该从(UI)线程运行。您不应该从 doInBackground 运行另一个 AsyncTask ,因为此方法是在非UI线程上执行的。

在你的情况下,我可以建议你两件事:

  1. 在单个请求中合并两个AsyncTaks的处理
  2. 从第一个任务的 onPostExecute 启动第二个AsyncTask。

答案 1 :(得分:11)

根据下面的帖子,您可以执行 Activity.runOnUiThread()在主线程(来自另一个线程)上运行Runnable。

理论上你可以这样做:

  • 运行异步任务
  • 在AsyncTask 中执行 Activity.runOnUiThread( Runnable )并从此runnable中启动一个新的AsyncTask

正如名称所说,Activity.runOnUiThread()在主线程上执行runnable

但这有点像黑客。

代码看起来像这样:(没有测试)

// first task
    (new AsyncTask<String, String, String>() {

        @Override
        protected String doInBackground(String... params) {
            ParentActitity.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    //second async stared within a asynctask but on the main thread
                    (new AsyncTask<String, String, String>() {

                        @Override
                        protected String doInBackground(String... params) {
                            // TODO Auto-generated method stub
                            return null;
                        }

                    }).execute();

                }
            });
            return null;
        }

    }).execute();

这个嵌套的例子不适合在制作中使用,因为(恕我直言)它接近不可读。

附加说明:

Activity.runOnUiThread(Runnable)静态!这就是为什么我的例子使用ParentActivity(.this).runOnUiThread(Runnable)。

答案 2 :(得分:6)

您无法在doInBackground()中执行此操作,但您可以从onProgressUpdate()开始,因为它在UI线程上运行。请记住,在3​​.0之后,它们将被放在同一个队列中,并且不会并行运行,请参阅executeOnExecutor

答案 3 :(得分:0)

请参阅AsyncTask()AsyncTask#execute()的文档。两者都声明必须在主UI线程上调用它们。

答案 4 :(得分:0)

我写的基本样本;

public class MainActivity extends Activity {

View view;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    view = new View(this);
    setContentView(view);

    view.setBackgroundColor(Color.RED);

    new FirstTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
}

private class FirstTask extends AsyncTask<Void, Void, Void>
{
    @Override
    protected Void doInBackground(Void... params) {

        new SecondTask().execute();
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Log.e("task","first");
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        view.setBackgroundColor(Color.GREEN);   
    }

}

private class SecondTask extends AsyncTask<Void, Void, Void>
{
    @Override
    protected Void doInBackground(Void... params) {
        Log.e("task","second");
        return null;
    }
}

}

答案 5 :(得分:0)

这很简单,您必须使用执行器:

new AsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{"param 1", "param 2"});

  

此方法通常与THREAD_POOL_EXECUTOR一起使用,以允许多个任务在AsyncTask管理的线程池上并行运行,但是您也可以使用自己的Executor进行自定义行为。

     

警告:通常并不需要一个线程池中的多个任务,因为它们的操作顺序未定义。例如,如果使用这些任务来共同修改任何状态(例如,由于单击按钮而写入文件),则不能保证修改的顺序。如果不进行仔细的工作,在极少数情况下,较新版本的数据可能会被较旧的版本覆盖,从而导致模糊的数据丢失和稳定性问题。最好以串行方式执行此类更改;为了确保无论平台版本如何,都可以对这些工作进行序列化,可以在SERIAL_EXECUTOR中使用此功能。

答案 6 :(得分:-1)

通过启动一个单独的线程来处理这部分数据管理,采取这些inet操作并参与其中并不是更好吗? 谷歌无处不在把它的模式,如果你看起来最接近它们都来自简单的类...这个API让android像蜘蛛网回调涉及回调...尝试理解java的基础知识并不难写一段好的代码。服务/内容解析器/接收器/加载器在某种程度上是有限的...线程几乎能够实现你想要的任何东西......

大多数人在没有考虑的情况下使用代码,甚至没有尝试理解它是如何工作的,并且理解什么是编程密钥。我尽量不使用我不知道的基础知识的代码。如果我需要我彻底研究它。我现在使用Java进行黑魔法,我认为它的数据流是A-&gt; B-&GT; C等.. 良好的流程是必不可少的

编辑:

是的,我为您解决了问题

有很多方法可以达到你想要的但不是我对你的作家代码的回应

  • 您可以使用IntentService类,它有一个内置队列---只需对每次传输使用单独的startService()调用。

  • 您可以使用主题 - 我的首选方式

  • 您可以使用服务

  • 您可以使用AsyncTaskLoader

  • 但不要使用 ASYNC TASK 如果你需要火力超过 TWO在ONCE相互链接他们都在MODERN PHONES RUNS上作为队列在一个线程上(ps。你可以在EXECUOR上运行它们作为一种解决方法)

由于JAVA 1.5任务与线程分离   - 添加了

自定义线程的意思是什么?

THREAD(正如我们所说)并不是一个线程类对象,但是它是THREAD CLASS的run()方法中定义的TASK,因此任何来自THREAD的CLASS类似于线程(也称为TASK)

    public synchronized void start() {
        checkNotStarted();

        hasBeenStarted = true;
        /** 
         * look at this line i'ts rerouting run() code of youre thread class  
         * to native method from there thread is created in pure C code 
         */
        nativeCreate(this, stackSize, daemon);
    }

就像在POSIX中那样:

int  pthread_create(pthread_t  *  thread, pthread_attr_t * attr, void *
   (*start_routine)(void *), void * arg);

从这一点开始,当操作系统通过同时执行多个任务执行多个任务时,我们可以讨论 MULTITASKING

因为 JAVA 1.5 Executor接口,它提供了一种将任务提交与每个任务运行方式的机制分离的方法,包括线程使用的详细信息,通常使用Executor而不是显式创建线程。你有很多执行者,其中一个是:ThreadPerTaskExecutor

class ThreadPerTaskExecutor implements Executor {
      public void execute(Runnable r) {
          new Thread(r).start();
      }
  }
     

此执行程序为每个任务生成一个新线程。

回到AsyncTask:

AsyncTaskM<P, P, R>.executeOnExecutor(Executor,P);
     

允许多个任务在由AsyncTask管理的线程池上并行运行,但是您也可以使用自己的Executor进行自定义行为。

是的,如果你没有意识到这一点,并且不知道其他人做了多少蜜蜂的话:)

  

我希望这一补充改变你对投票的看法。