[Toc]
基础认识
AsyncTask 是基于 Handler 进行封装的轻量级异步类,它是一个抽象类,我们要使用的时候需要实现其子类的以下 4 个方法
方法 | 描述 |
---|---|
onPreExecute() | 任务执行前被调用,执行在 UI 线程中,在这里我们做一些任务启动前的准备 |
doInBackground() | 执行在新的子线程中的,做异步任务的处理 |
onProgressUpdate() | 这个方法是在调用 publishProgress 的时候被调用的,是运行在 UI 线程的 |
onPostExecute() | 这个方法是任务执行完毕之后被调用的,是运行在 UI 线程中的 |
作用
- 实现多线程: 在工作线程中执行任务,如 耗时任务
- 异步通信、消息传递: 实现工作线程 & 主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作
AsyncTask 的三种状态
每个状态在一个任务的生命周期中只会被执行一次。 状态 | 描述 ---|--- PENDING | 等待(还没有开始执行任务) RUNNING | 执行中 FINSHED | 完成
AsyncTask 的内部执行过程
AsyncTask 的对象调用 execute 方法,execute 内部又调用了 executeOnExecutor ,onPreExecute 方法就是在这里被回调,之后将 AsyncTask 的参数封装成一个并发类,然后将其添加到排队线程池(SerialExecutor)中进行排队,如果当前有任务正在执行,则等待,否则 THREAD_POOL_EXECUTOR 执行该任务。在任务的执行过程中,通过 InternalHandler 将进度 pos(MESSAGE_POST_GROGRESS)发送到主线程中,此时会调用 onProgressUpdate 方法,任务执行完毕之后,InternalHandler 将结果 post(MESSAGE_POST_RESULT) 发送到主线程中,此时 onPostExecute 或者 onCancle 会被调用,任务执行到这里就结束了。
基本使用
-
举个栗子:在异步任务中每隔 1s 打印 1 ~ 10 的数值
- 我们不干预任务的执行过程,由任务执行完成,查看任务执行情况;
- 任务执行完成后,我们再点击开始,查看任务执行情况;
-
干预任务的执行过程,在任务执行期间点击取消,查看任务执行情况; ``` public class MainActivity extends AppCompatActivity { private TextView mText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mText = findViewById(R.id.text); progressAsycn1 = new ProgressAsycn(); findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { progressAsycn1.execute(1); }
}); findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { progressAsycn1.cancel(true); mText.append(String.format("取消任务%s\n",new Date().toString())); }
});
}
private ProgressAsycn progressAsycn1;
private class ProgressAsycn extends AsyncTask<Integer,Integer,String> {
// 这个方法是在启动之前被调用的,执行在 UI 线程中,在这里我们做一些任务启动前的准备
@Override
protected void onPreExecute() {
super.onPreExecute();
mText.append(String.format("准备执行%s\n",new Date().toString()));
}
// 这个方法是执行在新的线程的中的
@Override
protected String doInBackground(Integer... params) {
for (int i = params[0]; i <= 10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return "任务已经执行完毕";
}
// 这个方法是在调用 publishProgress 的时候被调用的,是运行在 UI 线程的
@Override
protected void onProgressUpdate(Integer... values) {
mText.append(String.format("工作进度:%d\n",values[0]));
}
// 这个方法是任务执行完毕之后被调用的
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mText.append(String.format("任务执行完毕%s\n",new Date().toString()));
}
/**
* 异步任务被取消时回调,即 AsyncTask 的对象调用了 cancel 方法