AsyncTask 面试解析

本文深入解析了Android的AsyncTask,包括它的基础认识、作用、三种状态和内部执行流程。通过示例展示了基本使用方法,并提出了执行过程中可能遇到的问题,如对象只能调用一次和取消任务的效果。文章还对关键源码进行了解析,涉及构造函数、execute()方法,以及cancel()方法的工作原理。最后总结了AsyncTask使用时的限制和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[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 的数值

    1. 我们不干预任务的执行过程,由任务执行完成,查看任务执行情况;
    2. 任务执行完成后,我们再点击开始,查看任务执行情况;
    3. 干预任务的执行过程,在任务执行期间点击取消,查看任务执行情况; ``` 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 方法
  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值