AsyncTask源码解析

来源:互联网 发布:显卡评测软件 编辑:程序博客网 时间:2024/04/29 03:42
本文会带领大家像看故事一样去理解AsyncTask的部分源码,首先我们来看一个AsyncTask的小程序
public class MainActivity extends Activity {private ProgressDialog dialog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dialog = new ProgressDialog(this);          dialog.setMax(100);          dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);          dialog.setCancelable(false);        new MyAsyncTask().execute();}private class MyAsyncTask extends AsyncTask<Void, Integer, Void>{@Overrideprotected Void doInBackground(Void... params) {for (int i = 1; i <= 100; i++) {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}publishProgress(i);}return null;}@Overrideprotected void onPreExecute() {dialog.show();super.onPreExecute();}@Overrideprotected void onProgressUpdate(Integer... values) {dialog.setProgress(values[0]);super.onProgressUpdate(values);}@Overrideprotected void onPostExecute(Void result) {if(dialog!=null){dialog.dismiss();}super.onPostExecute(result);}}}
运行效果图如下:


现在我来一步一步按照执行的顺序来分析各部分源码
首先当然是new AsyncTask(),好我们去到构造方法里面看看

//*****(1)******AsyncTask.java public AsyncTask() {        mWorker = new WorkerRunnable<Params, Result>() {//什么是WorkerRunnable看下面(2)            public Result call() throws Exception {//这个方法我们先不看待会调用的时候回来再看,我们严格按照代码执行的顺序来看                mTaskInvoked.set(true);                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                //noinspection unchecked                return postResult(doInBackground(mParams));            }        };        mFuture = new FutureTask<Result>(mWorker) {//看到这里一定很好奇什么是FutureTask,往下看(3),这里分析完后那么已经把new MyAsyncTask()弄完了,现在该干嘛?当然是execute(),继续往下看            @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 occured while executing doInBackground()",                            e.getCause());                } catch (CancellationException e) {                    postResultIfNotInvoked(null);                }            }        };    }
//******(2)*****AsyncTask.javaprivate static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {     Params[] mParams;}
知道什么是WorkerRunnable了吧,那好回到(1)继续

//*******(3)**********FutureTask.java public FutureTask(Callable<V> callable) {//callable即我们的mWorker,后面的代码中还要用到mWorker,我们还要用它来调用call方法呢        if (callable == null)            throw new NullPointerException();        this.callable = callable;        this.state = NEW;       // ensure visibility of callable}
知道FutureTask是继承自Runnable的所以到此我们就开启了一个子线程
构造函数已经分析完了,现在该excute()了,进入execute()的源码(4)

//******(4)*******AsyncTask.javapublic final AsyncTask<Params, Progress, Result> execute(Params... params) {        return executeOnExecutor(sDefaultExecutor, params);//往下看这个方法(5)    }

//*******(5)************AsyncTask.javapublic 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;//mStatus设置为Running        onPreExecute();//onPreExecute()就是在这执行的        mWorker.mParams = params;//还记得前面的mWorker吗?它里面就一个Params[] mParams        exec.execute(mFuture);//exec为sDefaultExecutor对象,什么是sDefaultExecutor我们往下看(6)return this;    }

//********(6)************AsyncTask.javaprivate 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();//看这里,什么是r,就是我们的mFuture啊,不信你去(6)看看,好吧去看FutureTask的run()方法(7)                    } finally {                        scheduleNext();                    }                }            });            if (mActive == null) {                scheduleNext();            }        }        protected synchronized void scheduleNext() {            if ((mActive = mTasks.poll()) != null) {                THREAD_POOL_EXECUTOR.execute(mActive);            }        }    }

//**********(7)**********FutureTask.java//代码比较长是吧?别急我们只需要发来看关键部分即可 public void run() {        if (state != NEW ||            !UNSAFE.compareAndSwapObject(this, runnerOffset,                                         null, Thread.currentThread()))            return;        try {            Callable<V> c = callable;            //什么是callable还记得么?我们在前面讲了public FutureTask(Callable<V> callable){this.callable=callable}            //那不就是FutureTask构造方法的参数么—>mWorker,前面分析FutureTask的时候(1)我也提前讲过,不信自己去看            if (c != null && state == NEW) {                V result;                boolean ran;                try {                    result = c.call();//mWorker.call()到最前面的看(1)                    //postResult(doInBackground(mParams))主要看这个方法就可以了,而且参数使我们熟悉的doInBackground(mParams),往下看(8)                    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);        }    }

//*********(8)***********AsyncTask.java  private Result postResult(Result result) {        @SuppressWarnings("unchecked")        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,                new AsyncTaskResult<Result>(this, result));        message.sendToTarget();        return result;    }
对于上面的代码没有什么疑问吧?就是把message发送到sHandler去处理,那么下面看sHandler是个什么东西?他是InternalHandler的对象,看InternalHandle(9)


//********(9)*********AsyncTask.javaprivate static class InternalHandler extends Handler {        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})        @Override        public void handleMessage(Message msg) {            AsyncTaskResult result = (AsyncTaskResult) msg.obj;            switch (msg.what) {                case MESSAGE_POST_RESULT://这个是有postResult发出来的,说明当postResult执行完之后这里就该执行啦                    // There is only one result                    result.mTask.finish(result.mData[0]);                    //result是什么?AsyncTaskResult的对象,那么就来看看AsyncTaskResult是什么,往下看(10)                    //OK知道AsyncTaskResult是什么了吧?mTask不就this么当前的AsyncTask对象啊,它调用finish方法。什么是finish()*****(11)                    break;                case MESSAGE_POST_PROGRESS:                //这里啥时候回执行呢?别担心下面我来告诉你,看下面的publishProgress()******(12)               //Ok又回到这里了                    result.mTask.onProgressUpdate(result.mData);//onProgressUpdate()这个也是我们熟悉的家伙吧。好啦到此为止我们就分析完啦                    break;            }        }    }

/*******(10)**********AsyncTask.javaprivate static class AsyncTaskResult<Data> {        final AsyncTask mTask;        final Data[] mData;        AsyncTaskResult(AsyncTask task, Data... data) {            mTask = task;            mData = data;        }    }
知道AsyncTaskResult是什么了吧,那回到(9)继续看

//********(11)**********AsyncTask.javaprivate void finish(Result result) {        if (isCancelled()) {            onCancelled(result);        } else {            onPostExecute(result);//又看到我们熟悉的东西了吧        }        mStatus = Status.FINISHED;//这里mStatus的值变成了FINISHED,看完这里回到(9)    }

/*********(12)***********AsyncTask.java protected final void publishProgress(Progress... values) {        if (!isCancelled()) {            sHandler.obtainMessage(MESSAGE_POST_PROGRESS,                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();        }    }
跟上面的postResult很像吧?虽然写法不一样都是发送信息给sHandler处理,这里的msg.what=MESSAGE_POST_PROGRESS,赶快去sHandler里面看看

最后总结一下onPreExecute()是在UI线程中执行的,doInBackground(Params... params)是在子线程中执行,该线程是在mFuture这个对象开辟的,它里面的run()调用mWorker的call()从而执行了postResult(doInBackground(Params...params)),publishProgress(Progress... values)因为要实时的获取进度所谓要在doInBackground中执行,从而也是在子线程中执行的。onProgressUpdate()和finish()是在通过sHandler来处理的而sHandler是属于UI线程中的,所以这两个方法都是在UI线程中进行
onPostExecute()是在finish()中调用的所以它也是在UI线程中执行!!!

好了分析完毕

0 0
原创粉丝点击