AsyncTask源码分析

   AsyncTask作为官方设计的一种轻量的异步工具类,代码小巧,虽然不同的Android有一些差异问题,在比较新的版本里也标记为Deprecated,现在使用的也比较少了,但是有关异步设计还是很值得学习。具体源码分析是以Android P进行,frameworks\base\core\java\android\os\AsyncTask.java

  1. AsyncTask是一个抽象类,使用的时候一般通过子类来创建。在构造的时候会创建了一个处理后台工作的mWorker和关联的任务mFuture。

    public abstract class AsyncTask<Params, Progress, Result> {
       ...
       private final WorkerRunnable<Params, Result> mWorker;
       private final FutureTask<Result> mFuture;
       public AsyncTask() {
            mWorker = new WorkerRunnable<Params, Result>() {
                public Result call() throws Exception {
                    mTaskInvoked.set(true);
    
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    Result result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                    return postResult(result);
                }
            };
    
            mFuture = new FutureTask<Result>(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);
                    }
                }
            };
        }
    
      private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
            Params[] mParams;
      }
    
    }
    
    
  2. execute()执行流程

     @MainThread
     public final AsyncTask<Params, Progress, Result> execute(Params... params) {
            return executeOnExecutor(sDefaultExecutor, params);
     }
    

    从@MainThread注解,可以看出这个方法必须在主线程调用。其中sDefaultExecutor是一个定义为静态内部类Executor的实例,是AsyncTask默认的Executor,并且无法自定义为自己的Executor,代码如下:

        public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
        private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
        
        private static class SerialExecutor implements Executor {
            final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
            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) {
                    THREAD_POOL_EXECUTOR.execute(mActive);
                }
            }
        }
        
        /** @hide */
        public static void setDefaultExecutor(Executor exec) {
            sDefaultExecutor = exec;
        }
    

    具体executeOnExecutor()代码如下:首先会对当前的运行状态进行检查,如果处于就绪等待运行或者运行完成,会抛出异常。状态没有问题的话,就开始运行,先是执行前准备 onPreExecute(),接着开始上面提到的后台工作mWorker和任务mFuture。

    mWorker#中call()执行了**Result result = doInBackground(mParams);**,mWorker执行完成后,mFuture#done()就会通过 postResultIfNotInvoked(get())方法就结果消息发送给Handler。

        @MainThread
        public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
                Params... params) {
            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.mParams = params;
            exec.execute(mFuture);
    
            return this;
        }
    

    postResultIfNotInvoked()具体代码如下:mTaskInvoked和mCancelled是通过AtomicBoolean一种不加锁机制来保证变量多线程同步,通过变量名称可以看出相应的用途。postResultIfNotInvoked()的作用是将结果封装成AsyncTaskResult通过消息发送给Handler处理

        private final AtomicBoolean mCancelled = new AtomicBoolean();
        private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
        
        private void postResultIfNotInvoked(Result result) {
            final boolean wasTaskInvoked = mTaskInvoked.get();
            if (!wasTaskInvoked) {
                postResult(result);
            }
        }
        private Result postResult(Result result) {
            @SuppressWarnings("unchecked")
            Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                    new AsyncTaskResult<Result>(this, result));
            message.sendToTarget();
            return result;
        }
        
        @SuppressWarnings({"RawUseOfParameterizedType"})
        private static class AsyncTaskResult<Data> {
            final AsyncTask mTask;
            final Data[] mData;
    
            AsyncTaskResult(AsyncTask task, Data... data) {
                mTask = task;
                mData = data;
            }
        }
    

    Handler处理结果:消息为MESSAGE_POST_RESULT时,代表任务执行完成,通过上面的AsyncTaskResult定义,即执行Asynctask#finish()方法,任务执行完成,回调**onPostExecute(result);消息为MESSAGE_POST_PROGRESS时,就回调进度更新**onProgressUpdate()**,相应的这个消息是在我们执行publishProgres()发出。

        private static InternalHandler sHandler;
        ...
        private static class InternalHandler extends Handler {
            public InternalHandler() {
                super(Looper.getMainLooper());
            }
    
            @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
            @Override
            public void handleMessage(Message msg) {
                AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
                switch (msg.what) {
                    case MESSAGE_POST_RESULT:
                        // There is only one result
                        result.mTask.finish(result.mData[0]);
                        break;
                    case MESSAGE_POST_PROGRESS:
                        result.mTask.onProgressUpdate(result.mData);
                        break;
                }
            }
        }
    
        private void finish(Result result) {
            if (isCancelled()) {
                onCancelled(result);
            } else {
                onPostExecute(result);
            }
            mStatus = Status.FINISHED;
        }
    
      @WorkerThread
        protected final void publishProgress(Progress... values) {
            if (!isCancelled()) {
                getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                        new AsyncTaskResult<Progress>(this, values)).sendToTarget();
            }
        }
    
  3. 总结

    • AsyncTask中在进行耗时操作时,在主线程做一些准备工作,即onPreExecute()

    • AsyncTask中通过mWorker、mFuture、sDefaultExecutor来处理子线程耗时任务,即doInBackground()

    • AsyncTask中通过sHandler来处理任务完成与进度更新回调,即onPostExecute()与onProgressUpdate()

    • AsyncTask中有使用volatile和AtomicBoolean两种机制来保证多线程间变量的同步

    • AsyncTask中三个参数的意义可以看上面过程中参数的传递,各个方法是在子线程还是在主线程执行,可以看@WorkerThread和 @MainThread注解,也可以上面过程。这里就不总结了-_-

  4. 类图与流程图
    AsyncTask类图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值