从实现上来说 AsyncTask 封装了Thread 和 Handler 通过 AsyncTask 可以更加方便地执行后台任务以及在主线程中访问UI
但是AsyncTask 并不适合进行特别耗时的后台任务,对于特别耗时的任务来说 建议使用线程池
AsyncTask基本使用:
public class MyTask extends AsyncTask<String ,Integer , Long> {
private int count ;
@Override
protected void onPreExecute() {
super.onPreExecute();
//在主线程中执行 在异步任务之前 此方法会调用 一般用于做一些准备工作
count = 0;
}
@Override
protected Long doInBackground(String... params) {
//在线程池中执行 此方法用于执行异步任务 params 参数表示异步任务的输入参数
//在此方法中可以通过 publishProgress(); 方法来更新任务进度 这个方法会调用onProgressUpdate 回调 此外
//此方法需要返回计算结果给 onPostExecute
for (int i = 0; i < 10; i++) {
count = count + 10;
publishProgress(count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//在主线程中执行 当后台任务的执行进度发生改变时此方法会被调用
//这里接收的value 就是上面传下来的
s1.setProgress(values[0]);
}
@Override
protected void onPostExecute(Long aLong) {
super.onPostExecute(aLong);
//在主线程中执行,在异步任务执行之后 次方法被调用 返回的参数是
// Toast.makeText(MainActivity.this, "Finish", Toast.LENGTH_SHORT).show();
LogUtil.fussenLog().d(TimeUtils.getTime1(System.currentTimeMillis()));
}
}
这个是模拟网址解析或者下载等任务。解释一下s1 是seekbar 代表进度的。
调用:
new MyTask().execute("");
以上就是基础使用方法。
使用AsyncTask 需要注意一下几个限制条件:
1 AsyncTask必须在主线程中加载
2 AsyncTask的对象必须在主线程中调用
3 execute方法必须在UI线程中调用
4 不要在程序中直接调用 onPreExecute 等四个方法
5 一个AsyncTask对象只能执行一次,即只能调用一次execute方法
6 Android1.6之前,AsyncTask是串行执行任务的 ,Android1.6的时候AsyncTask
开始采用线程池里处理并行任务,但是从Android3.0开始,为了避免AstncTask所带来的并发错误
AsyncTask又采用一个线程来串行执行任务。尽管如此,在Android3.0以及后续版本中,我们仍可以通过AysncTask
的executeOnExecututor 方法来并行执行任务
关于最后一条 验证:
分别在Android 4.1.1 和 Android 2.3.3 分别再点击事件里面 执行 new MyTask().execute("asd"); 五次
4.1.1 是时间叠加的就说明是串行的 3.0以上要并行的话 调用 executeOnExecututor new MyTask().executeOnExecutor(MyTask.THREAD_POOL_EXECUTOR , "");
OK 收工 具体源码在 书中11.2 里面 P392开始