AsyncTask源码分析

来源:互联网 发布:网络打印机安装失败 编辑:程序博客网 时间:2024/06/08 06:31

一. 先了解Java中的FutureTask与Callable

// 创建Callable线程对象Callable<String> callable = new Callable<String>() {    @Override    public String call() throws Exception {        Thread.sleep(2000);        return "这是Callback Runnable的执行结果";    }};// 创建FutureTask对象, 用于包装Callable, 通过FutureTask.get()可以获取到Callable的返回值FutureTask<String> futureTask = new FutureTask<String>(callable) {    @Override    protected void done() {        super.done();        // 任务执行完成后会回调该方法        Log.e("TAG", "任务执行完毕, FutureTask的done方法在子线程中被回调");        try {            Log.e("TAG", get());        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }    }};// 开启线程执行任务new Thread(futureTask).start();// 直接在主线程中通过futureTask.get().toString()获取Callable结果, 会阻塞主线程, 直到获取到Call的返回值为止try {    Log.e("TAG", "尝试在主线程中获取Callable的Result值");    String callableResult = futureTask.get().toString();    Log.e("TAG", "任务执行完毕, 主线程从阻塞中恢复");    Log.e("TAG", callableResult);} catch (InterruptedException e) {    e.printStackTrace();} catch (ExecutionException e) {    e.printStackTrace();}

这里写图片描述

二. AsyncTask源码

1. 通过execute(Params)提交任务, 最终会执行executeOnExecutor()

public final AsyncTask<Params, Progress, Result> execute(Params... params) {    return executeOnExecutor(sDefaultExecutor, params);}/**  * 最终会通过这个方法执行AsyncTask任务 */public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,        Params... params) {     // 通过这个判断说明了, 一个AsyncTask对象只能执行一次任务, 否则会抛出IllegalStateException异常     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();    // 这个mWorker成员变量即为CallableRunnable    mWorker.mParams = params;    // mFuture为FutureTask, 是把mWorker当做实参来实例化的    // exec为sDefaultExecutor, 是一个SerialExecutor, 是一个顺序顺序执行的线程执行者    exec.execute(mFuture);    return this;}/*** * 这个线程序列执行者是static的 * 也就是说所有的AsyncTask实例调用的execute()任务任务时都是在这个池中排队执行的 */private static class SerialExecutor implements Executor {    // 线程队列    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();    Runnable mActive;    // 当一个AsyncTask实例在执行任务时, 其他线程会进入阻塞状态    public synchronized void execute(final Runnable r) {        // 开启了一个新线程执行任务        mTasks.offer(new Runnable() {            public void run() {                try {                    // 已经在子线程中了, 所以直接调用run()方法                    r.run();                } finally {                    // 当前任务执行完后, 也会执行下一个任务                    scheduleNext();                }            }        });        // 若没有任务, 则会执行下一个任务        if (mActive == null) {            scheduleNext();        }    }    protected synchronized void scheduleNext() {        if ((mActive = mTasks.poll()) != null) {            THREAD_POOL_EXECUTOR.execute(mActive);        }    }}

2. 当线程执行完成后, 如何回调onPostExecute(Result result)的呢?

由上面的源码可知, 我们执行的任务为一个mFuture(FutureTask的实例), 所以当线程执行完毕后Callable会有一个返回值才对, 我们先看看Callable的返回值是什么

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result>{    Params[] mParams;}/** * AsyncTask的构造函数 */public AsyncTask() {    // mWoker的实例化过程, WorkerRunnable这个类implements了Callable    mWorker = new WorkerRunnable<Params, Result>() {        public Result call() throws Exception {            // 表明该任务被调用            mTaskInvoked.set(true);            Result result = null;            try {                // 设置线程的优先级                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                // 我们可以看到doInBackground是在该Callable线程中回调的                result = doInBackground(mParams);                Binder.flushPendingCommands();            } catch (Throwable tr) {                mCancelled.set(true);                throw tr;            } finally {                // 将result通过Hanlder切换到主线程去执行                Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,                new AsyncTaskResult<Result>(this, result));                message.sendToTarget();            }            return result;        }    };    // mFuture的实例化过程    mFuture = new FutureTask<Result>(mWorker) {        // 当Callable执行完成之后会回调done方法        @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);            }        }    };}

3. 在主线程中执行onProgressUpdate() 和 onPostExecute()方法

/**  * 这里就是getHanlder获得的Hanlder对象 */private static class InternalHandler extends Handler {    public InternalHandler() {        super(Looper.getMainLooper());    }    @Override    public void handleMessage(Message msg) {        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;        switch (msg.what) {            case MESSAGE_POST_RESULT:                // 在主线程中处理doInBackground的返回值                result.mTask.finish(result.mData[0]);                break;            case MESSAGE_POST_PROGRESS:                // 在主线程中更新doInBackgroud的任务进度                result.mTask.onProgressUpdate(result.mData);                break;        }    }}
原创粉丝点击