AsyncTask源码阅读

2017-12-13  本文已影响0人  Noblel
        AsyncTask task = new AsyncTask<Void,Void,Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    //执行一些耗时操作,连接网络,读取大型数据库
                    publishProgress();//反馈当前进度
                    return null;
                }
    
                @Override
                protected void onPreExecute() {
                    //一调用就执行的方法  UI线程
                    super.onPreExecute();
                }
    
                @Override
                protected void onPostExecute(Void aVoid) {
                    super.onPostExecute(aVoid);
                    //执行完返回
                }
        };
    
    task.execute();

带着思想和疑惑去读取源码 遇到不懂得学会跳过。

AsyncTask为什么只能执行一次?

    //判断AsyncTask状态
    if (mStatus != Status.PENDING) {//检测是否是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();
    onPreExecute();
    
    mWorker.mParams = params;
    
    exec.execute(mFuture);
    
    return this;

Ctrl + F 查找到"mFuture = " "mWorker = "

    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;
        }
    };
    
    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实现了RunnableFuture 所以他是一个线程,最后执行run()方法

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

调用c.call方法 也就是mWorkr的call()方法,然后执行doInBackground(mParams)(执行子线程中,已经不是主线程了),mWorkr的finally中执行postResult(result)方法

private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
            new AsyncTaskResult<Result>(this, result));
    message.sendToTarget();//通过handler发消息让其切换到主线程
    return result;
}

/**
 * Sends this Message to the Handler specified by {@link #getTarget}.
 * Throws a null pointer exception if this field has not been set.
 */
public void sendToTarget() {
    target.sendMessage(this);
}

点MESSAGE_POST_RESULT进去看handler中的处理,可以看到是调用了task的finish方法

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

调用isCancelled()方法判断是否取消,如果取消就会调用onCancelled()方法,否则调用onPostExecute(result);所以这两个方法都是在主线程中

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

总结:

execute()方法一调用就会去判断状态,如果状态不对就会抛异常,然后会把状态置为Running,然后执行onPreExecute(),开一个线程执行doInBackground(),doInBackground()执行完毕之后会利用Handler发送消息切换主线程中,然后执行onPostExecute()方法,最后把状态置为FINISHED。

上一篇 下一篇

猜你喜欢

热点阅读