美文网首页
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源码阅读

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