美文网首页
AsyncTask源码阅读

AsyncTask源码阅读

作者: Noblel | 来源:发表于2017-12-13 10:38 被阅读0次
        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。

相关文章

  • AsyncTask异步任务的源码详细解析

    1、AsyncTask基本使用: 2、AsyncTask源码阅读,点击asyncTask.execute("www...

  • AsyncTask 源码阅读

    基于 Android-24 AsyncTask 是安卓 sdk 提供的一个异步框架,用来解决耗时任务线程和主线程之...

  • AsyncTask源码阅读

    带着思想和疑惑去读取源码 遇到不懂得学会跳过。 AsyncTask为什么只能执行一次? Ctrl + F 查找到"...

  • AsyncTask源码阅读

    1.AsyncTask的三个泛型Params,Progress和Result Params:doInBackgro...

  • Android AsyncTask 源码解析

    标签:Android AsyncTask 源码解析 1.关于AsyncTask 1.1 什么是AsyncTask?...

  • Android源码之AsyncTask

    参考 本文源码版本:Pie 9.0.0_r3 在线源码地址:AsyncTask.java 1 AsyncTask简...

  • Android AsyncTask源码阅读

    AsyncTask 封装了新建后台工作线程再用Handler更新UI的过程。在官方文档也说明这个类最好用于时间短的...

  • AsyncTask源码阅读笔记

    写在前面 感觉最近自己需要多读书,所以在以后的一段时间里可能都是笔记形式的文了,希望自己能厚积薄发吧。 Async...

  • Android源码解析-Asynctask

    android源码分析-AsyncTask 我们一般创建一个AsyncTask的任务代码如下: 下面开始分析源码:...

  • AsyncTask异步任务类

    目录介绍 01.先看下AsyncTask用法 02.AsyncTask源码深入分析2.1 构造方法源码分析2.2 ...

网友评论

      本文标题: AsyncTask源码阅读

      本文链接:https://www.haomeiwen.com/subject/mukaixtx.html