AsyncTask源码分析

我们通常在执行异步任务加载图片或者一些耗时任务的时候会用到AsyncTask这个类。今天看了AsyncTask的源码,做一个简单的分析

用法:

(1)定义自己的异步类

class MyAsyn extends AsyncTask{

        @Override protected Object doInBackground(Object[] params) {
            return null;
        }

        @Override protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override protected void onPostExecute(Object o) {
            super.onPostExecute(o);
        }
    }

(2)调用
MyAsyn myAsyn = new MyAsyn();
myAsyn.execute();

源码分析

首先来看一下AsyncTask的构造方法

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

代码比较长 其实主要就是对mFuture和mWorker进行了初始化,可以看到在初始化mWorker的时候 重写了call方法,里面正好有我们会调用的doInBackground 方法。而在初始化mFuture的时候则传入了mWorker作为参数,这个后面再讲,构造函数就这么多,接着我们来看一下execute()方法

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

这个方法又调用了executeOnExecutor()方法,并且传入了一个sDefaultExecutor,这个参数一会儿再说。接着我们再来看一下executeOnExecutor()方法。的定义如下:

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

代码很短,我们看到了一个熟悉的函数 onPreExecute()方法,接着调用 exec.execute(mFuture);方法,exec是什么呢,其实就是调用当前方法传进来的sDefaultExecutor,我们得找到这个变量的定义呀,接着看一下这个变量:

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

这个类比较简单,我们主要看execute方法和scheduleNext方法。execute方法中通过offer方法向mTasks添加callback其实就是往队列里面添加一系列的任务,添加一个之后,判断mActive的值是否为空,第一次为空,则调用scheduleNext方法,接着调用THREAD_POOL_EXECUTOR.execute(mActive);我们来看一下THREAD_POOL_EXECUTOR这个静态变量:

  /**
     * 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;
    }

这个静态变量的初始化是在静态代码块中进行的,当调用THREAD_POOL_EXECUTOR.execute(mActive);方法时,便新开了一个线程进行任务处理,调用mFuture的run方法:

    public void run() {
        if (state != NEW ||
            !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

可以看到在mFuture的run方法中有一个callable,实际上这个callable就是mFuture在初始化时传入的mWorker,该方法最终调用worker的call方法,进而调用doInBackground方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值