【问题标题】:What change did really happen in Async Task after Android Gingerbread?在 Android Gingerbread 之后,Async Task 真正发生了什么变化?
【发布时间】:2012-06-15 06:05:41
【问题描述】:

在 android 2.3 之后,真正的 Android 团队在 Async 任务中做了哪些改变。当我执行以下代码时,我在 Android 2.3 和 3.0 中都得到了相同的结果。

package com.sample.asynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class AsyncTaskTestActivity extends Activity {
    private static final String TAG = "AsyncTaskTestActivity";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 1; i <= 20; i++) {
            TestTask testTask = new TestTask(i);
            testTask.execute();
        }
    }

    private static class TestTask extends AsyncTask<Void, Integer, Void> {
        int i;
        public TestTask(int i) {
            Log.i(TAG, "Constructor for " + i);
            this.i = i;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
            Log.i(TAG, "onPreExecute for " + i);
        }

        @Override
        protected Void doInBackground(Void... params) {
            Log.i(TAG, i + " Thread goes to sleep");
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Log.i(TAG, i + " Thread wakes up");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            Log.i(TAG, "onPostExecute for " + i);
        }
    }
}

我在 Gingerbread 中的假设:一次在一个线程池中执行 5 个异步任务。 我在 Honeycomb 中的假设:一次在一个线程池中执行 1 个异步任务。与并发执行完全一样。

但是,Gingerbread 和 Honeycomb 都同时执行 5 个异步任务。

当异步任务的数量增加到 140 时,我没有得到 java.util.concurrent.RejectedExecutionException

我的假设是否正确?里面到底发生了什么?

【问题讨论】:

    标签: java android multithreading android-asynctask threadpool


    【解决方案1】:

    我的假设是否正确?

    你的假设是正确的,嗯,有点。

    里面到底发生了什么?

    android.os.AsyncTask里面的默认执行器:

    ... ...
    
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    
    ... ...
    

    已在android.app.ActivityThread重置:

    ... ...
    
    // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
    // implementation to use the pool executor.  Normally, we use the
    // serialized executor as the default. This has to happen in the
    // main thread so the main looper is set right.
    if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
        AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }
    
    ... ...
    

    在 Android Gingerbread 之后,Async Task 真正发生了什么变化?

    查看 AsyncTask change history,更具体地说,是这个:

    Mar 17, 2011 - AsyncTask now uses the poll executor for apps up through HC MR1 and t…

    当异步任务的数量增加到 140 时,我没有收到 java.util.concurrent.RejectedExecutionException。

    这是任务总数和每个任务的执行时间的一个因素,在另一个世界中,任务总数为 140(大于 128),但是,线程池在任何给定的情况下分配的线程总数time 小于 128,换句话说,在您的情况下,总是有一些空闲线程(由于最后一个任务完成和释放资源)可用。您可以尝试增加每个任务的执行时间,例如 Thread.sleep(10000),这可能会给您带来 RejectedExecutionException。

    【讨论】:

    • 当异步任务超过 140 个时我没有收到错误消息?
    • if (data.appInfo.targetSdkVersion
    • 是的,我现在收到了 RejectedExecutionException。但我仍然不太清楚
    • @Ads,简单来说,140个任务并不意味着线程池需要分配140个线程,真正重要的是在任何给定时间分配了多少线程,取决于每个任务需要多长时间,线程池可能只需要 10 个线程来运行所有任务。如果在线程池中没有可用线程(所有128个线程都被占用)时提交下一个任务,则线程池将抛出RejectedExecutionException。
    【解决方案2】:

    此线程概述了 ICS 中 AsyncTask 的更改。该信息由 Google 员工提供,因此值得信赖。

    https://groups.google.com/forum/?fromgroups#!topic/android-developers/8M0RTFfO7-M

    【讨论】:

      【解决方案3】:

      AsyncTask 行为的变化还需要您在 ICS 及以上硬件上运行。

      见: http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-14
        • 1970-01-01
        • 2017-05-25
        相关资源
        最近更新 更多