同时运行多个 AsyncTasks —— 不可能吗?

发布于 2024-09-30 06:23:03 字数 1214 浏览 1 评论 0原文

我正在尝试同时运行两个 AsyncTasks。 (平台为Android 1.5、HTC Hero。) 然而,只有第一个被执行。这是一个简单的片段来描述我的问题:

public class AndroidJunk extends Activity {
 class PrinterTask extends AsyncTask<String, Void, Void> {
     protected Void doInBackground(String ... x) {
      while (true) {
       System.out.println(x[0]);
       try {
        Thread.sleep(1000);
       } catch (InterruptedException ie) {
        ie.printStackTrace();
       }
      }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new PrinterTask().execute("bar bar bar");
        new PrinterTask().execute("foo foo foo");

        System.out.println("onCreate() is done.");
    }
}

我期望的输出是:

onCreate() is done.
bar bar bar
foo foo foo
bar bar bar
foo foo foo

等等。但是,我得到的是:

onCreate() is done.
bar bar bar
bar bar bar
bar bar bar

第二个 AsyncTask 永远不会被执行。如果我更改execute() 语句的顺序,则只有foo 任务会产生输出。

我在这里错过了一些明显的事情和/或做了一些愚蠢的事情吗?不能同时运行两个AsyncTask吗?

编辑:我意识到有问题的手机运行 Android 1.5,我更新了问题描述。因此。我在运行 Android 2.1 的 HTC Hero 上没有这个问题。嗯...

I'm trying to run two AsyncTasks at the same time. (Platform is Android 1.5, HTC Hero.)
However, only the first gets executed. Here's a simple snippet to describe my problem:

public class AndroidJunk extends Activity {
 class PrinterTask extends AsyncTask<String, Void, Void> {
     protected Void doInBackground(String ... x) {
      while (true) {
       System.out.println(x[0]);
       try {
        Thread.sleep(1000);
       } catch (InterruptedException ie) {
        ie.printStackTrace();
       }
      }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new PrinterTask().execute("bar bar bar");
        new PrinterTask().execute("foo foo foo");

        System.out.println("onCreate() is done.");
    }
}

The output I expect is:

onCreate() is done.
bar bar bar
foo foo foo
bar bar bar
foo foo foo

And so on. However, what I get is:

onCreate() is done.
bar bar bar
bar bar bar
bar bar bar

The second AsyncTask never gets executed. If I change the order of the execute() statements, only the foo task will produce output.

Am I missing something obvious here and/or doing something stupid? Is it not possible to run two AsyncTasks at the same time?

Edit: I realized the phone in question runs Android 1.5, I updated the problem descr. accordingly. I don't have this problem with an HTC Hero running Android 2.1. Hmmm ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夕色琉璃 2024-10-07 06:23:03

AsyncTask 使用线程池模式来运行 doInBackground() 中的内容。问题最初是(在早期的 Android 操作系统版本中)池大小仅为 1,这意味着一堆 AsyncTasks 没有并行计算。但后来他们修复了这个问题,现在大小为 5,因此最多可以同时运行 5 个 AsyncTask。不幸的是我不记得他们到底在哪个版本中改变了这一点。

更新:

以下是当前 (2012-01-27) API 对此的说明:

首次引入时,AsyncTasks 在单个后台线程上串行执行。从 DONUT 开始,这被更改为线程池,允许多个任务并行操作。在HONEYCOMB之后,计划将其改回单线程,以避免并行执行导致的常见应用程序错误。如果你确实想要并行执行,你可以将此方法的executeOnExecutor(Executor, Params...) 版本与THREAD_POOL_EXECUTOR 结合使用;但是,请参阅那里的评论以获取有关其使用的警告。

DONUT是Android 1.6,HONEYCOMB是Android 3.0。

更新:2

请参阅 kabuko2012 年 3 月 7 日 1:27 发表的评论。

事实证明,对于使用“允许多个任务并行操作的线程池”的 API(从 1.6 开始到 3.0 结束),同时运行的 AsyncTask 的数量取决于已经传递执行的任务数量,但是还没有完成他们的doInBackground()

这是我在 2.2 上测试/确认的。假设您有一个自定义 AsyncTask,它仅在 doInBackground() 中休眠一秒钟。 AsyncTasks 在内部使用固定大小的队列来存储延迟任务。队列大小默认为 10。如果您连续启动 15 个自定义任务,则前 5 个任务将进入其 doInBackground(),但其余任务将在队列中等待空闲工作线程。一旦前 5 个任务完成并释放工作线程,队列中的任务就会开始执行。因此在这种情况下最多会同时运行 5 个任务。但是,如果您连续启动 16 个自定义任务,则前 5 个将进入其 doInBackground(),其余 10 个将进入队列,但对于第 16 个,将创建一个新的工作线程,因此它会立即开始执行。所以在这种情况下最多 6 个任务会同时运行。

可以同时运行的任务数量是有限制的。由于 AsyncTask 使用线程池执行器,其最大工作线程数有限 (128),并且延迟任务队列的大小固定为 10,因此如果您尝试执行超过 138 个自定义任务,应用程序将崩溃java.util.concurrent.RejectedExecutionException

从 3.0 开始,API 允许通过 AsyncTask.executeOnExecutor(Executor exec, Params... params) 方法使用自定义线程池执行器。例如,如果您不需要默认值 10,则可以配置延迟任务队列的大小。

正如 @Knossos 提到的,可以选择使用支持 v.4 库中的 AsyncTaskCompat.executeParallel(task, params); 来并行运行任务,而无需考虑 API 级别。此方法在 API 级别 26.0.0 中已弃用。

更新:3

这是一个简单的测试应用程序,用于处理任务数量、串行与并行执行:https://github.com/vitkhudenko/test_asynctask

更新:4(感谢 @penkzhou 指出这一点)

从 Android 4.4 开始 AsyncTask 的行为有所不同来自更新:2部分中的描述。 修复可防止AsyncTask 创建太多线程。

在 Android 4.4 (API 19) 之前,AsyncTask 具有以下字段:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(10);

在 Android 4.4 (API 19) 中,上述字段更改为:

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

此更改将队列的大小增加到 128 个项目,并减少了最大值线程数 = CPU 核心数 * 2 + 1。应用程序仍然可以提交相同数量的任务。

AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously. Unfortunately I don't remember in what version exactly they changed that.

UPDATE:

Here is what current (2012-01-27) API says on this:

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. After HONEYCOMB, it is planned to change this back to a single thread to avoid common application errors caused by parallel execution. If you truly want parallel execution, you can use the executeOnExecutor(Executor, Params...) version of this method with THREAD_POOL_EXECUTOR; however, see commentary there for warnings on its use.

DONUT is Android 1.6, HONEYCOMB is Android 3.0.

UPDATE: 2

See the comment by kabuko from Mar 7 2012 at 1:27.

It turns out that for APIs where "a pool of threads allowing multiple tasks to operate in parallel" is used (starting from 1.6 and ending on 3.0) the number of simultaneously running AsyncTasks depends on how many tasks have been passed for execution already, but have not finished their doInBackground() yet.

This is tested/confirmed by me on 2.2. Suppose you have a custom AsyncTask that just sleeps a second in doInBackground(). AsyncTasks use a fixed size queue internally for storing delayed tasks. Queue size is 10 by default. If you start 15 your custom tasks in a row, then first 5 will enter their doInBackground(), but the rest will wait in a queue for a free worker thread. As soon as any of the first 5 finishes, and thus releases a worker thread, a task from the queue will start execution. So in this case at most 5 tasks will run simultaneously. However if you start 16 your custom tasks in a row, then first 5 will enter their doInBackground(), the rest 10 will get into the queue, but for the 16th a new worker thread will be created so it'll start execution immediately. So in this case at most 6 tasks will run simultaneously.

There is a limit of how many tasks can be run simultaneously. Since AsyncTask uses a thread pool executor with limited max number of worker threads (128) and the delayed tasks queue has fixed size 10, if you try to execute more than 138 your custom tasks the app will crash with java.util.concurrent.RejectedExecutionException.

Starting from 3.0 the API allows to use your custom thread pool executor via AsyncTask.executeOnExecutor(Executor exec, Params... params) method. This allows, for instance, to configure the size of the delayed tasks queue if default 10 is not what you need.

As @Knossos mentions, there is an option to use AsyncTaskCompat.executeParallel(task, params); from support v.4 library to run tasks in parallel without bothering with API level. This method became deprecated in API level 26.0.0.

UPDATE: 3

Here is a simple test app to play with number of tasks, serial vs. parallel execution: https://github.com/vitkhudenko/test_asynctask

UPDATE: 4 (thanks @penkzhou for pointing this out)

Starting from Android 4.4 AsyncTask behaves differently from what was described in UPDATE: 2 section. There is a fix to prevent AsyncTask from creating too many threads.

Before Android 4.4 (API 19) AsyncTask had the following fields:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(10);

In Android 4.4 (API 19) the above fields are changed to this:

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

This change increases the size of the queue to 128 items and reduces the maximum number of threads to the number of CPU cores * 2 + 1. Apps can still submit the same number of tasks.

寂寞清仓 2024-10-07 06:23:03

这允许在具有 API 4+ (Android 1.6+) 的所有 Android 版本上并行执行:

@TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
void startMyTask(AsyncTask asyncTask) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    else
        asyncTask.execute(params);
}

这是 Arhimed 优秀答案的摘要。

请确保您使用 API 级别 11 或更高版本作为您的项目构建目标。在 Eclipse 中,即 Project >属性>安卓>项目构建目标不会破坏对较低 API 级别的向后兼容性。不用担心,如果您不小心使用了 minSdkVersion。如果您确实想使用 minSdkVersion 之后引入的功能,您可以使用注释来抑制这些错误,但在这种情况下,您需要自己注意兼容性。这正是上面代码片段中发生的情况。

2022 更新

请注意,AsyncTasks 很久以前就被弃用了。如果您使用 Kotlin,建议使用 Kotlin Coroutines,如果您依赖于在项目中使用 Java,则另一种选择是使用 java.util 中的 Executors .并发(来源)

This allows for parallel execution on all android versions with API 4+ (Android 1.6+):

@TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
void startMyTask(AsyncTask asyncTask) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    else
        asyncTask.execute(params);
}

This is a summary of Arhimed's excellent answer.

Please make sure you use API level 11 or higher as your project build target. In Eclipse, that is Project > Properties > Android > Project Build Target. This will not break backward compatibility to lower API levels. Don't worry, you will get Lint errors if your accidentally use features introduced later than minSdkVersion. If you really want to use features introduced later than minSdkVersion, you can suppress those errors using annotations, but in that case, you need take care about compatibility yourself. This is exactly what happened in the code snippet above.

Update 2022

Note that AsyncTasks got deprecated quite a while ago. If you use Kotlin, it is recommended to use Kotlin Coroutines and if you depend on using Java in your project, an alternative is to use Executors from java.util.concurrent. (source)

呆头 2024-10-07 06:23:03

让@sulai的建议更通用:

@TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
public static <T> void executeAsyncTask(AsyncTask<T, ?, ?> asyncTask, T... params) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    else
        asyncTask.execute(params);
}   

Making @sulai suggestion more generic :

@TargetApi(Build.VERSION_CODES.HONEYCOMB) // API 11
public static <T> void executeAsyncTask(AsyncTask<T, ?, ?> asyncTask, T... params) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    else
        asyncTask.execute(params);
}   
远昼 2024-10-07 06:23:03

只是将最新更新(更新 4)包含在 @Arhimed 的完美答案中,在 @sulai 的非常好的总结中:

void doTheTask(AsyncTask task) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // Android 4.4 (API 19) and above
        // Parallel AsyncTasks are possible, with the thread-pool size dependent on device
        // hardware
        task.execute(params);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Android 3.0 to
        // Android 4.3
        // Parallel AsyncTasks are not possible unless using executeOnExecutor
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    } else { // Below Android 3.0
        // Parallel AsyncTasks are possible, with fixed thread-pool size
        task.execute(params);
    }
}

Just to include the latest update (UPDATE 4) in @Arhimed 's immaculate answer in the very good summary of @sulai:

void doTheTask(AsyncTask task) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // Android 4.4 (API 19) and above
        // Parallel AsyncTasks are possible, with the thread-pool size dependent on device
        // hardware
        task.execute(params);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Android 3.0 to
        // Android 4.3
        // Parallel AsyncTasks are not possible unless using executeOnExecutor
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    } else { // Below Android 3.0
        // Parallel AsyncTasks are possible, with fixed thread-pool size
        task.execute(params);
    }
}
人间☆小暴躁 2024-10-07 06:23:03

Android 开发人员高效加载位图的示例使用自定义异步任务(从 jellybean 复制),因此您可以在低于 << 的 api 中使用executeOnExecutor。 11

http://developer.android.com/training/displaying-bitmaps/index.html html

下载代码并进入util包。

The android developers example of loading bitmaps efficiently uses a custom asynctask (copied from jellybean) so you can use the executeOnExecutor in apis lower than < 11

http://developer.android.com/training/displaying-bitmaps/index.html

Download the code and go to util package.

俏︾媚 2024-10-07 06:23:03

这是有可能的。
我的 android 设备版本是 4.0.4,android.os.Build.VERSION.SDK_INT 是 15

我有 3 个微调器

Spinner c_fruit=(Spinner) findViewById(R.id.fruits);
Spinner c_vegetable=(Spinner) findViewById(R.id.vegetables);
Spinner c_beverage=(Spinner) findViewById(R.id.beverages);

,而且我还有一个 Async-Tack 类。

这是我的微调器加载代码

RequestSend reqs_fruit = new RequestSend(this);
reqs_fruit.where="Get_fruit_List";
reqs_fruit.title="Loading fruit";
reqs_fruit.execute();

RequestSend reqs_vegetable = new RequestSend(this);
reqs_vegetable.where="Get_vegetable_List";
reqs_vegetable.title="Loading vegetable";
reqs_vegetable.execute();

RequestSend reqs_beverage = new RequestSend(this);
reqs_beverage.where="Get_beverage_List";
reqs_beverage.title="Loading beverage";
reqs_beverage.execute();

,工作正常。我的旋转器一一装好。我没有使用executeOnExecutor。

这是我的异步任务类

public class RequestSend  extends AsyncTask<String, String, String > {

    private ProgressDialog dialog = null;
    public Spinner spin;
    public String where;
    public String title;
    Context con;
    Activity activity;      
    String[] items;

    public RequestSend(Context activityContext) {
        con = activityContext;
        dialog = new ProgressDialog(activityContext);
        this.activity = activityContext;
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            ArrayAdapter<String> adapter = new ArrayAdapter<String> (activity, android.R.layout.simple_spinner_item, items);       
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spin.setAdapter(adapter);
        } catch (NullPointerException e) {
            Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        } catch (Exception e)  {
            Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
        super.onPostExecute(result);

        if (dialog != null)
            dialog.dismiss();   
    }

    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setTitle(title);
        dialog.setMessage("Wait...");
        dialog.setCancelable(false); 
        dialog.show();
    }

    @Override
    protected String doInBackground(String... Strings) {
        try {
            Send_Request();
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        return null;
    }

    public void Send_Request() throws JSONException {

        try {
            String DataSendingTo = "http://www.example.com/AppRequest/" + where;
            //HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            //Post header
            HttpPost httpPost = new HttpPost(DataSendingTo);
            //Adding data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

            nameValuePairs.add(new BasicNameValuePair("authorized","001"));

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);

            BufferedReader reader;
            try {
                reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                StringBuilder builder = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    builder.append(line) ;
                }

                JSONTokener tokener = new JSONTokener(builder.toString());
                JSONArray finalResult = new JSONArray(tokener);
                items = new String[finalResult.length()]; 
                // looping through All details and store in public String array
                for(int i = 0; i < finalResult.length(); i++) {
                    JSONObject c = finalResult.getJSONObject(i);
                    items[i]=c.getString("data_name");
                }

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

It is posible.
My android device version is 4.0.4 and android.os.Build.VERSION.SDK_INT is 15

I have 3 spinners

Spinner c_fruit=(Spinner) findViewById(R.id.fruits);
Spinner c_vegetable=(Spinner) findViewById(R.id.vegetables);
Spinner c_beverage=(Spinner) findViewById(R.id.beverages);

And also I have a Async-Tack class.

Here is my spinner loading code

RequestSend reqs_fruit = new RequestSend(this);
reqs_fruit.where="Get_fruit_List";
reqs_fruit.title="Loading fruit";
reqs_fruit.execute();

RequestSend reqs_vegetable = new RequestSend(this);
reqs_vegetable.where="Get_vegetable_List";
reqs_vegetable.title="Loading vegetable";
reqs_vegetable.execute();

RequestSend reqs_beverage = new RequestSend(this);
reqs_beverage.where="Get_beverage_List";
reqs_beverage.title="Loading beverage";
reqs_beverage.execute();

This is working perfectly. One by one my spinners loaded. I didn't user executeOnExecutor.

Here is my Async-task class

public class RequestSend  extends AsyncTask<String, String, String > {

    private ProgressDialog dialog = null;
    public Spinner spin;
    public String where;
    public String title;
    Context con;
    Activity activity;      
    String[] items;

    public RequestSend(Context activityContext) {
        con = activityContext;
        dialog = new ProgressDialog(activityContext);
        this.activity = activityContext;
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            ArrayAdapter<String> adapter = new ArrayAdapter<String> (activity, android.R.layout.simple_spinner_item, items);       
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spin.setAdapter(adapter);
        } catch (NullPointerException e) {
            Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        } catch (Exception e)  {
            Toast.makeText(activity, "Can not load list. Check your connection", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
        super.onPostExecute(result);

        if (dialog != null)
            dialog.dismiss();   
    }

    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setTitle(title);
        dialog.setMessage("Wait...");
        dialog.setCancelable(false); 
        dialog.show();
    }

    @Override
    protected String doInBackground(String... Strings) {
        try {
            Send_Request();
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        return null;
    }

    public void Send_Request() throws JSONException {

        try {
            String DataSendingTo = "http://www.example.com/AppRequest/" + where;
            //HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            //Post header
            HttpPost httpPost = new HttpPost(DataSendingTo);
            //Adding data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

            nameValuePairs.add(new BasicNameValuePair("authorized","001"));

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);

            BufferedReader reader;
            try {
                reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                StringBuilder builder = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    builder.append(line) ;
                }

                JSONTokener tokener = new JSONTokener(builder.toString());
                JSONArray finalResult = new JSONArray(tokener);
                items = new String[finalResult.length()]; 
                // looping through All details and store in public String array
                for(int i = 0; i < finalResult.length(); i++) {
                    JSONObject c = finalResult.getJSONObject(i);
                    items[i]=c.getString("data_name");
                }

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
金橙橙 2024-10-07 06:23:03

如果要并行执行任务,Android 3.0版本之后需要调用方法executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "your task name");但是这个方法在Android 3.0之前和1.6之后不存在,因为它自己并行执行,所以我建议你在项目中自定义自己的AsyncTask类,以避免在不同的Android版本中抛出异常。

if you want to execute tasks parallel,you need call the method executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "your task name") after Android version of 3.0; but this method is not exist before Android 3.0 and after 1.6 because it execute parallel by itself, So I suggest you customize your own AsyncTask class in your project,to avoid throw exception in different Android version.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文