在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);
}
}
}
我在Gingerbread中的假设:5异步任务一次在一个线程池中执行。 我在Honeycomb中的假设:1异步任务一次在一个线程池中执行。完全像并发执行。
但是,Gingerbread和Honeycomb同时执行5个异步任务。
当Async任务的数量增加到140时,我也没有得到java.util.concurrent.RejectedExecutionException
。
我的假设是否正确?那里面真的发生了什么?
答案 0 :(得分:3)
你的假设是正确的,好吧,等等。
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);
}
... ...
查看AsyncTask change history,更具体地说,检查一下:
Mar 17, 2011 - AsyncTask now uses the poll executor for apps up through HC MR1 and t…
这是每个任务的总任务数和执行时间的因素,在另一个世界中,总任务数是140(大于128),但是,任何给定的线程池分配的线程总数时间小于128,换句话说,在你的情况下总有一些空闲线程(由于上一个任务完成和释放资源)。你可以尝试增加每个任务的执行时间,例如Thread.sleep(10000)
,这可能会给你RejectedExecutionException。
答案 1 :(得分:1)
此主题概述了ICS中对AsyncTask的更改。该信息由Google员工提供,因此值得信赖。
https://groups.google.com/forum/?fromgroups#!topic/android-developers/8M0RTFfO7-M
答案 2 :(得分:0)
AsyncTask行为的变化还要求您在ICS及以上硬件上运行。
请参阅: http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html