9

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

这甚至可能吗?如果是,我怎样才能做到这一点?

后期编辑:

我的想法是我启动一个异步任务,它将从 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 中调用(但这将需要我修改很多代码)

4

7 回答 7

15

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

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

  1. 将两个 AsyncTaks 的处理合并到一个请求中
  2. 从您的第一个任务的onPostExecute启动您的第二个 AsyncTask 。
于 2013-10-22T14:30:48.450 回答
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)。

于 2013-10-22T14:37:29.197 回答
6

你不能这样做,doInBackground() 但你可以从onProgressUpdate()例如,因为它在 UI 线程上运行。请记住,在 3.0 之后它们将被放在同一个队列中并且不会并行运行,请参阅executeOnExecutor

于 2013-10-22T14:34:42.027 回答
0

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

于 2013-10-22T14:41:16.880 回答
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;
    }
}

}
于 2013-10-23T05:00:54.890 回答
0

很简单,你必须使用 Executor:

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

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

警告:允许多个任务从线程池并行运行通常不是人们想要的,因为它们的操作顺序没有定义。例如,如果这些任务用于修改任何共同的状态(例如由于单击按钮而写入文件),则无法保证修改的顺序。如果不仔细工作,在极少数情况下,较旧版本的数据可能会覆盖较新版本的数据,从而导致难以理解的数据丢失和稳定性问题。此类更改最好​​按顺序执行;为了保证无论平台版本如何都可以序列化此类工作,您可以将此函数与 SERIAL_EXECUTOR 一起使用。

于 2018-08-24T22:16:05.537 回答
-1

通过启动一个单独的线程来处理这部分数据管理,采取这几个 inet 操作并让它们参与不是更好吗?google 到处放它的模式,如果你看起来最接近它们都是从简单的类派生的……这个 API 使 android 像一个涉及回调的蜘蛛网回调……试着理解 java 的基础知识,写一篇文章并不难好的代码。服务/内容解析器/接收器/加载器以某种方式受到限制......线程几乎能够实现你想要的任何东西......

你们中的大多数人不假思索地使用代码,甚至没有尝试理解它是如何工作的,也没有理解编程的关键是什么。我尽量不使用我不知道基础的代码。如果我需要,我会彻底研究它。我现在用 Java 来做黑魔法,我认为它是 DATA FLOW A-> B-> C 等等 ..好的 FLOW 是必不可少的

编辑:

是的,我为你的问题写了解决方案

有很多方法可以实现您想要的,但这不是我对您编写器代码的回应

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

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

  • 你可以使用服务

  • 你可以使用 AsyncTaskLoader

  • 但是,如果您需要同时触发两个以上的相互链接,则不要使用ASYNC TASK , 它们都在 MODERN PHONES 上作为 QUEUE 在单个线程上运行(ps。您可以在 EXECUOR 上运行它们作为解决方法)

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

自定义线程是什么意思

线程(正如我们所说的)不是线程类对象,但它是在线程类的 run() 方法中定义的任务,因此任何从线程派生的类仍然开始线程(又名任务)

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

从这一点开始,我们可以谈论操作系统在一段时间内通过同时执行多个任务时执行多任务

由于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 进行自定义行为。

是的,如果您不适应并且对其他人不了解足够的啤酒,请这样做:)

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

于 2015-07-02T22:32:22.563 回答