AsyncTask源码解读

来源:互联网 发布:waf 源码 编辑:程序博客网 时间:2024/05/22 07:45

虽然说Asynctask很久没用都没用了,现在大部分使用RxJava,Retorfit……但是作为源码分析来讲,我认为还是可以看看的,其实以前看过好多次的,但是从来没有自己整理过,前段时间整理电脑里面的资料,发现了我当时看AsyncTack的流程图,于是,我就对着流程图再来了一遍。

首先是AsyncTask的简单使用:

AsyncTask的使用:        AsyncTask task = new AsyncTask<Void, Void, Void>() {            @Override            protected void onPostExecute(Void aVoid) {                super.onPostExecute(aVoid);                //执行完成返回的方法,在UI线程            }            @Override            protected void onPreExecute() {                //一调用就会执行的方法  运行在UI线程                super.onPreExecute();            }            @Override            protected Void doInBackground(Void... params) {                //执行一些耗时的操作 比如连接网络去读取数据,读取大型数据库 运行在主线程中                return null;            }        };        task.execute();

当调用者执行task.execute()方法之后,该方法去调用executeOnExecutor方法:

public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,            Params... params) {        //做了一些判断,非等待执行状态,第一次进来的状态是默认的Status.PENDING        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.PENDING        //所以会执行下面的代码        mStatus = Status.RUNNING;        //所以这个代码是一调用就会执行的方法        onPreExecute();        mWorker.mParams = params;        exec.execute(mFuture);        return this;        }
这样也就解释了AsyncTask 为什么只能执行一次的问题


接着会执行exec.execute(mFuture);而execute是一个抽象方法,传递的参数是一个runnable,
那么这个runnable是哪里来的呢?是在我们new AsyncTask的时候创建的

public AsyncTask() {        //这个mWorker就是后面执行run方法所要用到的Callable        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;            }        };        //FutureTask继承自Runnable        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是在我们new AsyncTask的时候就会创建的,mFuture的爷爷是Runnable,既然有了runnable,那么肯定会有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 {                //这是在执行new AsyncTask中mWorkr的call方法                    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);        }    }

在run()方法中会调用我们在new Asynctask的时候WorkRunnable的call方法  
在mWorker的call()方法中然后再去调用  

result = doInBackground(mParams);

再次贴出来

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;            }        };
由此可见doInBackground(mParams);就是运行在线程中,不是主线程
然后我们执行拿到result之后在线程中通过handler切换到主线程去
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;    }

处理消息:

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;            }        }
finish方法:

     private void finish(Result result) {        if (isCancelled()) {            onCancelled(result);        } else {            onPostExecute(result);        }        mStatus = Status.FINISHED;      }

finish会去判断有没有取消,如果是取消了就会调用onCancelled()方法,否则就是onPostExecute() 执行在主线程中了。


总结:
我们在new AsyncTask的时候,同时会去创建一个WorkerRunnable,他是一个抽象类,实现了Callable,也会去创建一个线程FutureTask,他实现了Runnable接口,当我们
ececute()方法一调用就会去判断状态,如果状态不对就会抛异常,然后会把状态置为Running ,然后执行onPreExecute(), 开一个线程执行 doInBackground(),
 doInBackground()执行完毕之后会利用Handler发送消息切换主线程中,然后执行onPostExecute()方法,最后把状态置为FINISHED

最后我们再结合流程图来看看






原创粉丝点击