欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AsyncTask使用及实现原理 二

程序员文章站 2022-03-08 10:06:50
...

AsyncTask是如何更新进度

上一篇我们讲了AsyncTask 的基本使用及原理分析,但是篇幅有点长了,最后没有介绍在执行异步任务时是如何更新进度的。这篇我们接着上一篇继续介绍AsyncTask是如何跟新进度的。

在这之前我们先来介绍进度执行及更新的两个方法。

        /**
         * 任务的执行进度
         * @param values
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

这个是进度的监听方法,再看下进度的执行方法。

 

 protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

这个方法是要放在异步执行方法中来执行的,也就是在doInBackground 方法中调用publishProgress方法将进度参数写入,然后onpProgressUpdate方法就会执行。大概流程就是这样,下面我们来看publishProgress具体是如何来实现的。

isCancelled() 用来判断当前任务是否取消了,如果没有取消,则通过handler方法发送消息。

public final boolean isCancelled() {
        return mCancelled.get();
    }

那么又是如何判断任务取消的,只要知道mCancelled 在哪里set值就能找到了,它本身是AtomicBoolean 变量名,借用别人的一些理解 AtomicBoolean :其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入。接着看:

public final boolean cancel(boolean mayInterruptIfRunning) {
        mCancelled.set(true);
        return mFuture.cancel(mayInterruptIfRunning);
    }

 

也就是说当我们调用了cancel方法后该任务将会被取消。扯的有点远了,我们回到主干上publishProgress方法。

这个时候它会通过handler发送一条消息,MESSAGE_POST_PROGRESS,上一篇我们讲过,asyncTask内部是内置了handler的,并且获取的是主线程的looper。

简单看下AsyncTaskResult类

private static class AsyncTaskResult<Data> {
        final AsyncTask mTask;
        final Data[] mData;

        AsyncTaskResult(AsyncTask task, Data... data) {
            mTask = task;
            mData = data;
        }
    }

它是一个内部私有类,有两个参数,一个是AsyncTask 一个是自定义类型泛型数组Data,通过new 这个类将参数放在其中,通过handler发送消息,接收到消息后再将msg.obj转为AsyncTaskResult<?>,实现主线程和ui线程切换。

 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;
            }
        }
result.mTask.onProgressUpdate(result.mData); 通过重写AsyncTask 的onProgressUpdate方法实现进度更新。

这样我们就可以实现异步任务进度更新工作了。

 

https://blog.csdn.net/zmx729618/article/details/52767736

 

相关标签: 源码