AsnyTask的源码解析

AnsyTask主要用来进行异步任务处理的,抽时间看了下AnsyTask的源码,记录一下过程。

类和成员变量的理解

先看了下他的类和属性,先对变量的意思有个大概的了解,可能有些出入。

一些类

-AsyncTaskResult

持有一个AsyncTask对象和一个数组,这个数组就是我们在onProgressUpdate或者onPostExecute中,在UI线程更新UI的回调数据

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

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

-InternalHandler

看到Hnadler肯定就猜想,在程序的运行过程中肯定有哪里会发送hanlder,去处理。这里,MESSAGE_POST_RESULT是一个任务结束了(可能是取消了,也可是执行完了);MESSAGE_POST_PROGRESS是任务还在持续进行

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    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;
        }
    }
}

-WorkerRunnable

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
}

是一个抽象类,且是Callable的子类。而他的初始化是在AsnyTask的构造方法中完成。

-FutureTask<>

FutureTask<> 是实现了RunnableFuture<>,而RunnableFuture<>则是继承了Runnable和Future。
FutureTask实现了Future的一些方法,如开启计算、取消计算、查询计算结果等,这里的计算,可以理解为我们的任务,计算开启或取消,对应任务的开启和取消等。但是查询计算结果只有在计算完成后才能通过get()方法获得,在计算没有完成前get()方法是阻塞的。当计算完成后,除非runAndReset(),否则不能重启或者取消计算。

这个对象的创建也是在AsnyTask的构造方法中完成。

-AtomicBoolean

理解为一种状态更新的标志,true或false,但是不能有boolean直接替换

-SerialExecutor

private static class SerialExecutor implements Executor {
    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
    Runnable mActive;

    public synchronized void execute(final Runnable r) {
        mTasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });
        if (mActive == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((mActive = mTasks.poll()) != null) {
            THREAD_POOL_EXECUTOR.execute(mActive);
        }
    }
}

SerialExecutor也是Executor的子类,重写了execute的方法,有序的执行队列里面的runnable

属性的理解

//大致意思是获取可用处理器的Java虚拟机的数量。 
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

//希望在核心线程池中最少有2个最多4个线程,通常比cpu数少一个更好,因为可以避免后台工作而引起CPU饱和
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));

//最大线程池数,cpu数*2+1
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;

//没有任务时线程活动的时间
private static final int KEEP_ALIVE_SECONDS = 30;

//一个线程工厂用于创建新的线程
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private final AtomicInteger mCount = new AtomicInteger(1);

    public Thread newThread(Runnable r) {
        return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
    }
};

//一个阻塞队列,放置执行的runnable,队列长度为128
private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);

//一个可同时执行多个线程池的执行器
public static final Executor THREAD_POOL_EXECUTOR;

//静态代码块,创建线程池的执行者,并赋值给上面的THREAD_POOL_EXECUTOR
static {
    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,sPoolWorkQueue, sThreadFactory);
    //设置为true,作用是让线程没有任务的时候也一直存在而不会停止  
    threadPoolExecutor.allowCoreThreadTimeOut(true);
    
    THREAD_POOL_EXECUTOR = threadPoolExecutor;
}

/*
 * 这个执行器按顺序一次执行一个任务,而这个顺序对指定的进行是全局的
 */
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

//handler发送消息的两个标志
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;

//默认的执行器
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

//一个handler
private static InternalHandler sHandler;

//一个比较核心的属性,是callable的子类
private final WorkerRunnable<Params, Result> mWorker;

//又是一个核心属性
private final FutureTask<Result> mFuture;

//一个标志task进行情况枚举状态,有还没有开始(PENDING)、正在进行(RUNNING)、结束(FINISHED)三个状态
private volatile Status mStatus = Status.PENDING;
    
//一个任务是否取消的状态标志
private final AtomicBoolean mCancelled = new AtomicBoolean();

//任务是否在运行的标志
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();

AsnyTask的构造方法

public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                Result result = doInBackground(mParams);
                Binder.flushPendingCommands();
                return postResult(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);
                }
            }
        };
    }

构造方法中主要是做了两件事,分别初始化了WorkerRunnable的对象mWorker和FutureTask的对象mFuture。


- 初始化mWorker时,new了一个callable(),并实现了callable的call()方法,在call()方法中设置了任务的状态,调用了doInbackground(mParams)得到结果,最后调用postResult(result)。

mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
           //设置任务的是在运行状态
            mTaskInvoked.set(true);    
           
           //运行在子线程
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            
            //把传进来的参数传到doInBackground,对应我们的回调
            Result result = doInBackground(mParams);
            Binder.flushPendingCommands();
            
            return postResult(result);
        }
    };

在postResult(result)中,看到调用了handler发送异步消息,这就和前面的InternalHandler连接上了

private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

在InternalHandler的handleMessage()中,对应MESSAGE_POST_RESULT的处理是:

case MESSAGE_POST_RESULT:
    // There is only one result
     result.mTask.finish(result.mData[0]);
    break;

而finish()中:

private void finish(Result result) {  
    if (isCancelled()) {    //如果是取消的结束
        onCancelled(result);  
    } else {               //是task完成的结束,对应onPostExecute的回调
        onPostExecute(result);  
    }  
    mStatus = Status.FINISHED;  //最后把任务的状态置成FINISH
}  

- 再来看mFuture的初始化

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

初始化时,把mWorker作为参数传进去,并重写了Future的done()方法,done()会执行postResultIfNotInvoked(get()),其中get()方法是获取的mWorker的call()的返回的结果

postResultIfNotInvoked(get()):

private void postResultIfNotInvoked(Result result) {
    //获取任务的状态,但是在初始化mWorker时,该值已经被初始化为true,所以下面的if基本不会执行
    final boolean wasTaskInvoked = mTaskInvoked.get();  
    if (!wasTaskInvoked) {
        postResult(result);
    }
}

最后来看AnsycTas的excute()方法

 @MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}

excute调用了executeOnExecutor(sDefaultExecutor, params),看属性赋值,sDefaultExecutor = SerialExecutor(),前面已经提过,SerialExecutor就是按照顺序去挨个执行里面的task

其中executeOnExecutor(sDefaultExecutor, params):

@MainThread
public final AsyncTask<Params, Progress, Result>executeOnExecutor(Executor exec,Params... params) {
    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.RUNNING;

        onPreExecute();

        mWorker.mParams = params;
        exec.execute(mFuture);

        return this;
    }

在这个方法中,先判断当前的状态是否是Status.PENDING,然后把当前的状态置为Status.RUNNING,调用了onPreExecute(),对应了onPreExecute()的回调,可在主线程中做预处理。随即开始把 exec.execute(mFuture),及执行runnable。

exec即为sDefaultExecutor,就是我们前面说过的静态代码块里创建的线程池,这个线程池大小为cpu数量*2+1+阻塞线程数量128,虽然有一个数量大小的限制,但是SerialExecutor 里面的execute()可以看出,其实是一个任务一个任务执行的,及时并发量超过线程池大小,也不会出错。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值