按照Android的文档,AsyncTask设计用来在UI线程执行短期后台操作。它使用起来非常方便,不用用户去维护threads 或者handlers。AsyncTask作为一个Thread 和Handler的Helper类设计出来的。它不是一个通用的线程框架。AsyncTask应该作为一个短期后台操作来用。一般使用在几秒数量级的任务中。如果要使用长期的后台操作任务,需要使用service 或者是使用ThreadPoolExecutor and FutureTask。
在新版本Android SDK中AsyncTask,应该注意在默认情况下AsyncTask是在一个单线程中调用队列中的Task。例如:有多个AsyncTask任务同时开始调用。但是执行的时候是串行的。
在早期Android SDK版本中,AsyncTask是并行执行的。在HONEYCOMB以后sdk中,AsyncTask 改为串行操作。但是仍可以使用asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, param);
实现并行操作。
下面的例子就是一个例子。
使用参数AsyncTask.THREAD_POOL_EXECUTOR时,这个参数定义为:
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;
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
可以看出来,允许并行线程的数量与processors有关。默认情况下是5个线程。
用户可以自己定义线程的数量,通过调用这个函数。
public static ExecutorService exec = Executors.newFixedThreadPool(10);
程序代码如下:
用户可以自己定义线程的数量,通过调用这个函数。
public static ExecutorService exec = Executors.newFixedThreadPool(10);
下载地址:http://download.csdn.net/detail/yuxiaohui78/8388297
public class MainActivity extends Activity implements View.OnClickListener{
public static final int INTERVAL = 100;
public static final int TASK_SIZE = 50;
public static ExecutorService exec = Executors.newFixedThreadPool(10);
CheckBox parallelCheckBox = null;
CheckBox parallelCheckBox2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById (R.id.start_tasks).setOnClickListener(this);
parallelCheckBox = (CheckBox)findViewById (R.id.checkbox);
parallelCheckBox2 = (CheckBox)findViewById (R.id.checkbox2);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.start_tasks){
MyTask s = new MyTask ((TextView)findViewById (R.id.task1_tv));
MyTask s1 = new MyTask ((TextView)findViewById (R.id.task2_tv));
MyTask s2 = new MyTask ((TextView)findViewById (R.id.task3_tv));
MyTask s3 = new MyTask ((TextView)findViewById (R.id.task4_tv));
MyTask s4 = new MyTask ((TextView)findViewById (R.id.task5_tv));
MyTask s5 = new MyTask ((TextView)findViewById (R.id.task6_tv));
if (parallelCheckBox2.isChecked()){
s.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 1");
s1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 2");
s2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 3");
s3.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 4");
s4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 5");
s5.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "Task 6");
}else if (parallelCheckBox.isChecked()){
s.executeOnExecutor(exec, "Task 1");
s1.executeOnExecutor(exec, "Task 2");
s2.executeOnExecutor(exec, "Task 3");
s3.executeOnExecutor(exec, "Task 4");
s4.executeOnExecutor(exec, "Task 5");
s5.executeOnExecutor(exec, "Task 6");
}else{
s.execute("Task 1");
s1.execute("Task 2");
s2.execute("Task 3");
s3.execute("Task 4");
s4.execute("Task 5");
s5.execute("Task 6");
}
}
}
class MyTask extends AsyncTask <String, Integer, String>{
TextView tv = null;
public MyTask (TextView t){
tv = t;
}
@Override
protected String doInBackground(String... params) {
String s = params[0];
int i = 0;
while (i++ < TASK_SIZE)
try{
Thread.sleep(INTERVAL);
Log.i("yxh", "doInBackground In Task============>" + s);
this.publishProgress(i);
}catch (Exception e){
}
return s;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
@Override
protected void onProgressUpdate(Integer... values) {
tv.setText(values[0] + "/" + TASK_SIZE);
super.onProgressUpdate(values);
}
}
}
默认AsyncTask执行效果:
用下面参数的执行效果:
Executors.newFixedThreadPool(10)
使用下面参数的执行效果,开始只有5个任务并行执行,当线程池中有空闲的时候才会执行最后一个线程:
AsyncTask.THREAD_POOL_EXECUTOR
AsyncTask 存在的问题:
不管使用哪种并行执行的参数,在应用load过高的时候,很多时候会出现 AsyncTask的成员函数doInBackground调用不及时,出现delay的情况。即没有在onPreExecute调用后立即被执行。目前还没有找到怎样解决这个问题的方法。所以,AsyncTask最理想的应用是用在后台单一小任务上。如果要并发多个任务可以考虑java传统的Thread.