AsyncTask能同时工作吗?

4

AsyncTask是同时工作还是先来先服务?

例如,我有3个具有相同接口类和相同监听器函数的AsyncTasks。同时执行3个AsyncTasks。哪个AsyncTask的响应将显示在监听器函数中?

疑问:

1. AsyncTask是并行运行还是先来先服务? 2. 如果AsyncTask以并行方式运行,如何处理所有AsyncTasks的相同监听器函数?

Nb:疑问2是因为在不使用AsyncTask进行多个请求时收到第一个响应。(Web Api响应)。

提前感谢。


每次调用AsyncTask时,您是否正在创建一个新的实例? - CodeDaily
@TonnyBaya 我正在像这样开始异步操作 new MyAsynktask().execute(); - SARATH V
2个回答

3

如果需要处理多个请求,可以使用ThreadPoolExecutor

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    new callApi().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, location);
} else {
    new callApi().execute(location);
}

线程池模式

AsyncTask使用线程池模式来运行doInBackground()中的任务。

线程池模式是指创建多个线程来执行多个任务的一种方式。它基本上是一个容器,多个线程在队列中等待不同的任务。

例如:

public class MultipleAsyncTask extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        runMultipleAsyncTask(); // Start Async Task
    }
    private void runMultipleAsyncTask() // Run Multiple Async Task
    {
        FirstAsyncTask asyncTask = new FirstAsyncTask(); // First
        if(AppUtil.isCurrentVersionHoneycombAndAbove()) // Above Api Level 13
        {
            asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
        else // Below Api Level 13
        {
            asyncTask.execute();
        }
        SecondAsyncTask asyncTask2 = new SecondAsyncTask(); // Second
        if(AppUtil.isCurrentVersionHoneycombAndAbove())// Above Api Level 13
        {
            asyncTask2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
        else // Below Api Level 13
        {
            asyncTask2.execute();
        }
    }
    //Start First Async Task:
    private class FirstAsyncTask extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected void onPreExecute()
        {
            Log.i("AsyncTask" ,"FirstOnPreExecute()");
        }
        @Override
        protected Void doInBackground(Void... params)
        {
            for(int index = 0; index < 50; index++)
            {
                Log.i("AsyncTask" ,"FirstAsyncTask");
                try
                {
                    Thread.sleep(100);
                }
                catch (InterruptedException exception)
                {
                    exception.printStackTrace();
                }
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result)
        {
            Log.d("AsyncTask" ,"FirstonPostExecute()");
        }
    }
    //Start Second Async Task:
    private class SecondAsyncTask extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected void onPreExecute()
        {
            Log.i("AsyncTask" ,"SecondOnPreExecute()");
        }
        @Override
        protected Void doInBackground(Void... params)
        {
            for(int index = 0; index < 50; index++)
            {
                Log.d("AsyncTask" ,"SecondAsyncTask");
                try
                {
                    Thread.sleep(100);
                }
                catch (InterruptedException exception)
                {
                    exception.printStackTrace();
                }
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void result)
        {
            Log.d("AsyncTask" ,"SecondOnPostExecute()");
        }
    }
}

输出:

FirstOnPreExecute()
SecondOnPreExecute()
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstAsyncTask
SecondAsyncTask
FirstonPostExecute()
SecondOnPostExecute()

像api请求这样的不同功能可以使用相同的异步任务:

boolean flag;
    @Override
    protected String doInBackground (String... params) {
        flag= params[0].endsWith("/repos");
        //other statements
    }

现在,在您的onPostExecute中:

if(flag){
    //parse one way
} else {
    //parse another way
}

你能解释一下 AsyncTask.THREAD_POOL_EXECUTOR 的工作流程吗? - SARATH V
如果我将同一个asyncTask用于不同的功能,例如API请求,会有什么影响? - SARATH V
@SARATHV 如果您有一个AsyncTask的多个URL,您必须在asynctask内部存储一个标志。 - Hemant Parmar
谢谢,我明白了逻辑。 - SARATH V

3
我同意 Hemant Parmar 给出的答案,但还有一些需要了解的事情,即每个 AsyncTask 的 onPreExecute() 在先来先服务的方式下执行,之后每个 AsyncTask 的 doInBackground() 方法同时运行。
因此,如果您执行以下操作:
new FirstAsyncTask().execute(); new SecondAsyncTask().execute();
那么 FirstAsyncTask() 的 onPreExecute() 将完成其执行并启动在后台执行的 FirstAsyncTask() 的 doInBackground(),然后 SecondAsyncTask() 将执行其 onPreExecute() 并在完成后也会执行 SecondAsyncTask() 的 doInBackground()。现在,第一个和第二个异步任务的 doInBackground() 都将同时运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接