在Android姜饼之后,异步任务中真正发生了哪些变化


Android

2.3 之后,Android 团队在异步任务中做了哪些更改。当我执行以下代码时,我在 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);
        }
    }
}

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

但是,姜饼和蜂巢同时执行 5 个异步任务。

而且当异步任务的数量增加到 140.i 没有得到java.util.concurrent.RejectedExecutionException.

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

我的假设是否正确?

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

里面到底发生了什么?

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姜饼之后,异步任务中真正发生了哪些变化?

查看AsyncTask更改历史记录,更具体地说,这是:

2011 年 3 月 17 日 - AsyncTask 现在对通过 HC MR1 和 t

...

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

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

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

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

AsyncTask 行为的更改还要求您在 ICS 及以上硬件上运行。

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

相关内容

最新更新