多线程开发---AsyncTask源码解析

在android开发中线程有主副之别,即耗时操作要由子线程操作,然后主线程来更新Ui;handler就充当一个子线程和主线程切换的角色;但是相比于handler,AsyncTask更加轻量级;那么直接开始解析AsyncTask的源码:

1.AsyncTask的使用:

        //参一:Params, 参二:Progress, 参三:Result
        AsyncTask mAsync = new AsyncTask<String,Integer,String>(){
            //在开始之前完成初始化等一系列的准备工作
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }


            //在这个方法中处理耗时操作
            @Override
            protected String doInBackground(String... strings) {
                return null;
            }

            //接收处理完的返回值然后开始在UI线程中处理更新Ui的操作
            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
            }

            //在这里跟新进度条
            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
            }
        }.execute(new String[]{"haha"} );

首先来看在new AsyncTask的时候 传入的参数为(Paramas,Progress,Result);在这一步就确定了 耗时操作参数的类型,耗时操作完成之后的返回值类型,进度条progress值的类型

2.execute(Params… params)

    首先来看execute源码:
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

看的出来execute的真正实现方法是:executeOnExecutor,ok~接下来来看executeOnExecutor的具体实现:

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

在以上源码中,第一步是走的AsyncTask的onPreExecute();相当于数据初始化的准备工作;
之后是mWorker.mParams = params;很明显是个mWorker的mParams属性赋值;ok~ 那么接着来看mWork(WorkerRunnable)这个类的源码实现:

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }

以上代码看不出什么 那么据需看mWorker的具体实例化过程(即是new 该对象的过程):

    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                     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;
            }
        };

注意关键代码:result = doInBackground(mParams);在这里mWorker.Params已经赋值完毕;然后params的值赋值给doInBackground的参数;供开发者来实现,以params作为参数来做耗时处理,最后返回result;
接着回到executeOnExecutor方法中 :onPreExecute()—>oWorker.Pramas = pramas;接着来看:exec.execute(mFueture);
那么我们来看mFueture所代表的类实例化的源码:

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);
                }
            }
        };
    首先会走FutureTask的构造,将参数mWorker进行初始化的赋值:
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    在走完构造之后Future中的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);
        }
    }

这里的callable就是穿进来的参数mworker,然后调用mWorker的call方法返回耗时操作(供开发者实现并返回)的返回值,进行set(result)到线程池中(有兴趣要看下线程池的概念,这里先不解释)

这里写代码片
    ok~来看下new FutureTask<Result>(mWorker)关键的代码:
        postResultIfNotInvoked(get());
    先来看get()的实现:
public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }


@SuppressWarnings("unchecked")
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

可以看出来get()—>reprot(s) 而report返回是(V)x,就是outcome;
然后追溯outcome:
看到outcome在set(Result)中被赋值;

protected void set(V v) {
        if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
            outcome = v;
            U.putOrderedInt(this, STATE, NORMAL); // final state
            finishCompletion();
        }
    }

联系前面FutureTask实例化run()中通过set(result)到线程池,get()就是从先前的线程池中取出result;是不是恍然大悟;ok~这样我们就可以将:postResultIfNotInvoked(get());变化为postResultIfNotInvked(result)了;那么接下来看postResultIfNoInvoked的源码:

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

很明显是要利用handler将result回归主线程更新ui,顺着猜测往下看,来追溯,handleMessger()的方法:

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

迅速找到刚刚发送msg的what为MESSAGE_POST_RESULT;ok~接下来就简单了 获取result作为参数走到 result.mTask.finish(result.mData[0]);
那么来看finish的源码:

    private void finish(Result result) {
        if (isCancelled()) result = null;
        // 在主线程中调用更新界面的方法
        onPostExecute(result);
        mStatus = Status.FINISHED;
    }

显而易见,在finish中调用onPostExecute(result)来更新ui(开发者实现抽象方法onPostExecute(result)来更新ui)

到这里AsyncTask的源码解析就完成了,感谢阅读,期待一起进步,欢迎关注,谢谢~

猜你喜欢

转载自blog.csdn.net/soullines/article/details/77529282