博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AsyncTask源码分析
阅读量:5839 次
发布时间:2019-06-18

本文共 6942 字,大约阅读时间需要 23 分钟。

要研究Android的AsyncTask之前,要先搞明白FutureTask和Executor类:

 FutureTask是什么:

FutureTask实际上是一个任务的操作类,它并不启动新线程,只是在自己所在线程上操作,任务的具体实现是构造FutureTask时提供的,实现自Callable<V>接口,FutureTask不知道具体的任务是什么,它只知道如何调度任务,如:

  • 如何启动任务:在FutureTask的run()方法中(实现自Runnable.run()),调用Callable.call()方法来启动任务,Callable.call()方法中是任务的具体实现;
  • 如何取消任务:在cancel()里,中断执行任务的线程,记录任务结束状态,并调用done()方法来执行用户实现的操作;
  • 如何返回任务的运行结果:如果任务还在执行,则阻塞线程(使用LockSupport.park()),直到任务结束才返回结果,用户可以通过get()方法来获取结果,同样当任务运行结束时,会调用down()来执行用户实现的操作。

使用FutureTask的好处是,更轻松的对任务进行管理,而不是像Runnable那样扔进线程后就啥也不能做了。

 Executor是什么:

Executor顾名思义是任务执行者,它不关心是什么任务,只关心如何执行任务。Executor是个Interface,具体如何执行任务要看怎么实现这个接口,你可以这样实现:

class DirectExecutor implements Executor {
  @Override public void execute(Runnable r) { r.run(); } }

也可以这样实现:

class ThreadPerTaskExecutor implements Executor {
  @Override public void execute(Runnable r) { new Thread(r).start(); } }

这两种实现的区别显而易见,java文档还提供了另一个Executor实现的例子:

class SerialExecutor implements Executor {   final Queue tasks = new ArrayDeque();   final Executor executor;   Runnable active;   SerialExecutor(Executor executor) {     this.executor = executor;   }   @Override   public synchronized void execute(final Runnable r) {     tasks.offer(new Runnable() {       public void run() {         try {           r.run();         } finally {           scheduleNext();         }       }     });     if (active == null) {       scheduleNext();     }   }   protected synchronized void scheduleNext() {     if ((active = tasks.poll()) != null) {       executor.execute(active);     }   } }

这个实现的意思是,严格按照用户提交的顺序来执行任务。Android的AsyncTask就使用了这个例子。

AsyncTask是如何实现的:

AsyncTask实现的关键地方在构造函数和executeOnExecutor()函数里。

  • 首先看下构造函数:
public AsyncTask() {        mWorker = new WorkerRunnable
() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);           //任务的具体实现 return postResult(doInBackground(mParams)); } }; mFuture = new FutureTask
(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 occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } } }; }

 

代码中WorkerRunnable实现自Callable,所以mWorker就是任务的具体实现(call()中的doInBackground())。通过对FutureTask的说明可以知道,mFuture是mWorker的操作类,它不仅用来实现对AsyncTask任务的操作(cancel,get等),最主要的,实现了mWorker执行结束的操作:

private void postResultIfNotInvoked(Result result) {        final boolean wasTaskInvoked = mTaskInvoked.get();        if (!wasTaskInvoked) {            postResult(result);        }    }    private Result postResult(Result result) {        @SuppressWarnings("unchecked")        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,                new AsyncTaskResult
(this, result)); message.sendToTarget(); return result; } private static final InternalHandler sHandler = new InternalHandler(); private static class InternalHandler extends Handler { @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; } } } private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }

FutureTask和Handler共同实现了任务结束的操作,代码很简单,不赘述。

  • 接下来是executeOnExecutor()函数的实现:
public final AsyncTask
execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } public final AsyncTask
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; }

AsyncTask是通过execute或executeOnExecutor启动的,通过上边对Executor的介绍可以知道,在executeOnExecutor()中的exec.execute(mFuture)这一行就是根据exec的实现方式来启动mFuture了,问题的关键是exec是如何实现execute()的。在execute中可以看到AsyncTask提供了一个默认的sDefaultExecutor,这个sDefaultExecutor是什么呢:

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();    private static class SerialExecutor implements Executor {        final ArrayDeque
mTasks = new ArrayDeque
(); 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); } } }

默认情况下,sDefaultExecutor就是SerialExecutor类,通过源码可以看到,SerialExecutor是一个严格按照用户提交顺序来执行任务的执行者,其中scheduleNext()函数用来启动下一个任务:

 

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

 

THREAD_POOL_EXECUTOR就是真正启动任务的Executor:
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,            sPoolWorkQueue, sThreadFactory);

ThreadPoolExecutor是java自己实现的一种Executor,顾名思义,是个提供线程池的Executor。

由上可以知道,当调用AsyncTask的execute()函数时,AsyncTask会按用户提交任务的顺序,在线程池里串行的执行任务(当前任务运行结束,再运行下一个)。

当然用户也可以提供自己的Executor来改变AsyncTask的运行方式。

 

 

转载地址:http://favcx.baihongyu.com/

你可能感兴趣的文章
Oracle下建立dblink时的权限问题
查看>>
chrome浏览器,调试详解,调试js、调试php、调试ajax
查看>>
jQuery Ajax 回顾
查看>>
Python天天美味(8) - 字符串中的字符倒转
查看>>
点在多边形内算法,C#判断一个点是否在一个复杂多边形的内部
查看>>
如何在移动设备上搭建服务器承载自己的全景作品?
查看>>
iOS SQLite3数据库操作
查看>>
除了 iOS 和 Android,世界第三大移动系统是什么?
查看>>
35.7. FAQ
查看>>
深搜算法实例:老鼠走迷宫(一)
查看>>
VMWare网络设置的3中方式(转)
查看>>
支付这条线上 谁在赚钱谁在哭?
查看>>
机器学习之朴素贝叶斯分类
查看>>
亚信安全参加第六届全国等保技术大会 态势感知助力“等保2.0”落地
查看>>
【设计模式系列】--抽象工厂
查看>>
JqueryValidate 动态添加验证
查看>>
双活数据中心的架构
查看>>
大数据公司Palantir融得7亿美元 曾追踪拉登
查看>>
先行者长虹佳华超融合市场沙龙在京举行
查看>>
建立备份策略的重要性
查看>>