美文网首页
AsyncTask 源码分析

AsyncTask 源码分析

作者: 大盗海洲 | 来源:发表于2019-05-10 11:45 被阅读0次
未命名文件.jpg
https://www.jianshu.com/p/7f08641e3e3f
Android AsyncTask 源码解析
  • 创建SerialExecutor 线程池用于ArrayDeque. offer(FutureTask) 提交任务
  • 创建ThreadPoolExecutor 线程池(总长度=128(LinkedBlockingQueue)+10)execute(Runnable)执行任务

初始化创建对象

  • 创建InternalHandler,用于工作线程和主线程通讯
  • 创建线程WorkerRunnable ,重写call,处理异步操作,并暴露doInBackground方法
  • 创建FutureTask,以通过workerRunnable&get方法获取执行结果,该方法会阻塞直到任务返回结果
   /**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     */
    public AsyncTask() {
        this((Looper) null);
    }
 /**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     *
     * @hide
     */
    public AsyncTask(@Nullable Looper callbackLooper) {
      //callbackLooper=null,所以获取getMainHandler()
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);
      
        //WorkerRunnable implements Callable<Result> 创建有返回值的线程
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
              //设置线程优先级低于UI thread,减少对前台线程的影响
       Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    postResult(result);
                }
                return result;
            }
        };
        // Future就是对于具体的Runnable或者Callable任务的执行结果进行取
  //消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
        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);
                }
            }
        };
    }

通过单例创建一个内部handler, looper 是直接获取UI thread的looper

   private static Handler getMainHandler() {
        synchronized (AsyncTask.class) {
            if (sHandler == null) {
                sHandler = new InternalHandler(Looper.getMainLooper());
            }
            return sHandler;
        }
    }

回到 new AsyncTask()
Message将消息MESSAGE_POST_RESULT 发送到InternalHandler

    private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

   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) {
                case MESSAGE_POST_RESULT:
                    // There is only one result
                    //result.mTask =this(AsyncTask.finish)
                    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;
}

执行 new MyAsyncTask().execute();

public abstract class AsyncTask<Params, Progress, Result> {

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

  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);
            }
        }
    }

   @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }
@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();//1

        mWorker.mParams = params;
        //exec 指sDefaultExecutor
        exec.execute(mFuture);//

        return this;
    }
}


    private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;
      //exec.execute(mFuture);最后在这执行
        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);
            }
        }
    }
   /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    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;
    }

在doInBackground()方法中调用onProgressUpdate()

  @WorkerThread
    protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

相关文章

  • Android源码解析-Asynctask

    android源码分析-AsyncTask 我们一般创建一个AsyncTask的任务代码如下: 下面开始分析源码:...

  • AsyncTask异步任务类

    目录介绍 01.先看下AsyncTask用法 02.AsyncTask源码深入分析2.1 构造方法源码分析2.2 ...

  • AsyncTask源码分析

    前言 IntentService使用及源码分析 HandlerThread源码分析 AsyncTask使用及封装实...

  • AsyncTask 使用及封装实践

    前言 IntentService使用及源码分析 HandlerThread源码分析 AsyncTask使用及封装实...

  • Android - AsyncTask (SDK 24)

    利用AsyncTask给ListView异步加载图片 实现图文混排 链接 AsyncTask源码分析 知乎

  • 4.AsyncTask使用,原理

    资料 AsyncTask处理机制详解及源码分析-工匠若水 AsyncTask 源码解析-鸿洋 带你认识不一样的As...

  • AsyncTask带你更深入点看源码

    关键词 AsyncTask源码分析 FutureTask源码分析 快过年了,公司同事已经开始进行迁移之旅,目前来...

  • AsyncTask工作原理

    AsyncTask工作原理调用图 AsyncTask工作原理源码分析,建议配合调用图一起看 调用 AsyncTas...

  • AsyncTask源码分析

    一 AsyncTask使用的场景 在MainThread线程中执行耗时不长的最多几秒钟的后台工作。 二 Async...

  • AsyncTask源码分析

    Android中UI的更新主要在主线程中,而耗时操作一般在子线程中进行;我们可以通过handler发送消息的方式处...

网友评论

      本文标题:AsyncTask 源码分析

      本文链接:https://www.haomeiwen.com/subject/bgbioqtx.html