面试题之AsyncTask

AsyncTask其实就是对线程和线程池的封装,其内部方法有:

  • onPreExecute() 任务开始前回调方法,执行在主线程中
  • doInBackground() 任务执行中的操作,执行在子线程中
  • publishProgress(int progress) 发送任务进度,执行在子线程中
  • onProgressUpdate() 进度回调方法,执行在主线程中
  • onPostExecute() 任务执行结束方法,执行在主线程中

开启源码分析

public abstract class AsyncTask {
    //手机cpu的核数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    //线程池的核心大小(cpu的核数+1)
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    //线程池最大线程大小(核心大小*2+1)
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;
}
    //线程池的工厂
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);
        //创建新增的线程以AsyncTask为标识
        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };
    //静态线程池
    public static final Executor THREAD_POOL_EXECUTOR;
    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
    //一个静态的内部线程池(它是串行执行)
    private static class SerialExecutor implements Executor {
        final ArrayDeque mTasks = new ArrayDeque();
        Runnable mActive;

        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }
        //执行下一个线程任务
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                //这里我们可以看到真正执行任务的还是上面定义的SERIAL_EXECUTOR
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }
    //执行任务的线程池(指向SerialExecutor)
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    //执行任务的Callable接口的实现
    private final WorkerRunnable mWorker;
    //存放mWorker的任务栈
    private final FutureTask mFuture;
    //执行状态的枚举类型
    private volatile Status mStatus = Status.PENDING;

    public enum Status {
        /**
         * 准备
         */
        PENDING,
        /**
         * 执行中
         */
        RUNNING,
        /**
         * 结束
         */
        FINISHED,
    }
    //AsyncTask的构造函数
    public AsyncTask(@Nullable Looper callbackLooper) { 
        //设置当前的Handler为主线程的Handler,主要是getMainHandler()方法返回一个InternalHandler内部类
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);
        //设置mWorker
        mWorker = new WorkerRunnable() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                    //设置当前线程为THREAD_PRIORITY_BACKGROUND
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //调用doInBackground()方法执行耗时操作
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    //最终发送执行结果
                    postResult(result);
                }
                return result;
            }
        };
        //这里构建mFuture,将mWorker作为构造参数传入其中
        mFuture = new FutureTask(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(get());
                } catch (InterruptedException e) {
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
    //获取主线程Handler方法,返回值为InternalHandler内部类
    private static Handler getMainHandler() {
        synchronized (AsyncTask.class) {
            if (sHandler == null) {
                sHandler = new InternalHandler(Looper.getMainLooper());
            }
            return sHandler;
        }
    }

    //发送结果方法
    private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        //这里发送了一个MESSAGE_POST_RESULT标识的消息
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult(this, result));
        message.sendToTarget();
        return result;
    }

    //InternalHandler内部类
    private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                //监听消息类型为MESSAGE_POST_RESULT
                case MESSAGE_POST_RESULT:
                    //调用result.mTask(也就是AsyncTask)的finish()方法
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

    //finish方法
    private void finish(Result result) {
        //判断是否取消
        if (isCancelled()) {
            //调用取消的方法
            onCancelled(result);
        } else {
            //调用最终的onPostExecute()方法
            onPostExecute(result);
        }
        //并且将状态标识为FINISHED状态
        mStatus = Status.FINISHED;
    }
}

接下来我们看看我们调用AsyncTask的execute方法究竟执行了些什么操作

    @MainThread
    public final AsyncTask execute(Params... params) {
        //这里调用了executeOnExecutor()方法
        return executeOnExecutor(sDefaultExecutor, params);
    }

    @MainThread
    public final AsyncTask executeOnExecutor(Executor exec,
            Params... params) {
        //先去判断当前任务的Status状态,如果不是准备状态,就开始抛出异常
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                case RUNNING:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task is already running.");
                case FINISHED:
                    throw new IllegalStateException("Cannot execute task:"
                            + " the task has already been executed "
                            + "(a task can be executed only once)");
            }
        }
        //标识现在状态为执行中状态
        mStatus = Status.RUNNING;
        //调用onPreExecute()方法
        onPreExecute();
        //进行mWorker.mParams赋值
        mWorker.mParams = params;
        //这里调用了sDefaultExecutor.execute()方法,其实是执行了传入的mFuture中的Callable接口实现类mWorker的call()方法
        exec.execute(mFuture);

        return this;
    }

分析到这里整个源码的流程我们就分析结束了。

总结

从上面的一波猛如虎的分析中,我们可以整体的梳理一下AsyncTask的源码整体的执行流程。其内部有SerialExecutor内部类线程池(串行执行),Status状态标识枚举,WorkerRunnable等...
在我们调用AsyncTaskexecute方法的时候进行了Status的状态判断,并且调用了SerialExecutor线程池来执行任务,而真正执行的是传入的mFuture构造函数中的mWorkercall方法,在call方法中设置了当前线程为子线程,并且调用了doInBackground()方法,在其返回值完事后调用了postResult()方法,而在postResult()方法中发送了一个Message,通过InternalHandler来对消息进行处理,在其接收MESSAGE_POST_RESULT时候调用了AsyncTaskfinish()方法,在finish()方法中我们先去判断了是否取消的操作,执行了onPostExecute()方法,最终将Status状态设置为结束状态。至此我们就整体的梳理了AsyncTask的整体执行流程。

使用时候注意点

从以上源码分析中我们可以得出以下的几个使用注意点:

  1. AsyncTask的实例必须在主线程中创建
  2. AsyncTask的execute方法必须在主线程中调用
  3. 回调方法,android会自动调用
  4. 一个AsyncTask的实例,只能执行一次execute方法

你可能感兴趣的:(面试题之AsyncTask)