AsyncTask 简介
AsyncTask 是一个轻量级的异步任务类,它内部封装了Thread和Handler可以用它在线程池中执行后台异步任务,然后把执行进度和最终结果传递给主线程并在主线程中更新UI。
AsyncTask 参数
AsyncTask 是一个抽象的泛型类,提供了Params、Progress、Result三个泛型参数
Params:参数类型
Progress: 任务进度的类型
Result:任务返回结果类型
如果确实不需要传递具体的参数,可用Void来代替
AsyncTask 核心方法
- onPreExecute() 主线程执行,在异步任务执行前被调用,可用于做一些准备工作
- doInBackground(Params…params) 在线程池执行,在此方法中可以通过publishProgress方法类更新任务进度,publishProgress方法会调用onProgressUpdate方法,此方法最后还需将任务结果返回给onPostExecute方法
- onProgressUpdate(Progress..values) 在主线程执行,任务进度发生改变时此方法会被调用
- onPostExecute(Result result) 主线程执行,任务执行之后被调用,result参数是doInBackground方法的返回值
上面方法,正常执行顺序是onPreExecute先执行,接着是doInBackground,最后才是onPostExecute执行。 另外AsyncTask 还提供了onCancelled方法,同样在主线程中执行,当异步任务被取消时,onCancelled方法会被调用,这时候onPostExecute方法则不会被调用
AsyncTask 使用注意
- AsyncTask 对象必须在主线程中创建
- execute方法必须在UI线程中调用
- 不要再程序中直接调用它的四个核心方法
- 一个AsyncTask 对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常
- AsyncTask 在3.0及以后的版本中是采用一个线程来串行执行任务的,但是我们可以通过AsyncTask 的executeOnExecutor方法来并行执行任务
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findId();
}
private void findId(){
button1 = findViewById(R.id.btn_1);
button1.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == button1){
new MyAsyncTask("AsyncTask#1").
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
new MyAsyncTask("AsyncTask#2").
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
new MyAsyncTask("AsyncTask#3").
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
new MyAsyncTask("AsyncTask#4").
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
new MyAsyncTask("AsyncTask#5").
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
}
}
private static class MyAsyncTask extends AsyncTask<String,Integer,String>{
private String mName = "AsyncTask";
public MyAsyncTask(String mName){
super();
mName = mName;
}
@Override
protected String doInBackground(String... strings) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return mName;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Log.d("xj", s + "execute finish at : " +df.format(new Date()));
}
}
}
并行运行结果:可以看到他们的结束时间是一样的
09-13 16:12:20.441 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.443 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.444 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.445 AsyncTaskexecute finish at : 2018-09-13 16:12:20
09-13 16:12:20.446 AsyncTaskexecute finish at : 2018-09-13 16:12:20
串行运行时,5个任务共耗时15s,且时间间隔为3s