AsyncTask工作原理解析
来源:互联网 发布:ai mac中文版免费下载 编辑:程序博客网 时间:2024/06/05 07:00
因为这是我第一次写源码的解析,说得不清楚或者不正确的还望指正。
线程在android中扮演了很重要的角色,但归根到底就是主线程(UI线程)和子线程。在子线程中不能修改UI控件,而在主线程中又不能做耗时的操作。所以说如果既要做耗时的操作,又要修改UI控件的话,就会显得很麻烦,幸好android封装了这一功能,就是AsyncTask,里面是封装了线程池和Handler。
AsyncTask的调用是new MyAsyncTask().execute(),所以我们就从execute()开始看。
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { ...... mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
首先调用的是executeOnExecutor(Params… params),再调用executeOnExecutor(Executor exec,
Params… params)方法。
在这里面,我们看到了onPreExecute(),就是做一些准备工作的。再往下看,出现了mWorker.mParams = params;
exec.execute(mFuture);
这两句,那么mWorker是什么,mFuture又是什么,还有那个exec。
好,我们现在先来看mWorker.。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }private final WorkerRunnable<Params, Result> mWorker;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); } };
原来,mWorker是Callable子类,而Callble其实相当于就是一个Runnable线程,run()方法换成了call()方法而已。跟Runnable不同的是Callble是有返回值的,而Runnable是没有的。
接着看下去,Result result = doInBackground(mParams),原来最耗时的doInBackground()在这里执行,而且还有一个返回值,Result。最后的postResult(result),肯定就是将结果返回主线程。这部分稍后再讲。
我们再看看mFuture是什么?
private final FutureTask<Result> mFuture;public AsyncTask() { ............ 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这个类,这个类究竟是什么呢?我们来看看它的定义:
public class FutureTask<V> implements RunnableFuture<V>{ public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }}
原来又是一个线程,而这个线程是实现了RunnableFuture接口。RunnableFuture是可以被多线程下执行,并且能够异步的取得结果。
mFuture在构造函数里面传入了参数mWorker,而在done()方法里面执行了postResultIfNotInvoked(get());
get()是表示获取mWorker的call的返回值,即Result。然后调用postResultIfNotInvoked(),下面来看看这个方法
private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } }
哈哈,原来又是有postResult(result),又是返回主线程,通知控件修改,这块一会再讲。
来到这里,已经说明了mWorker和mFuture这两个了。接着就是讲exec.execute(mFuture)中的exec了,就是一开始提到的那里,没有忘记吧!
exec原本是executeOnExecutor(ExecuteOnExecutor exec,…)中传进来的参数,那我们再看之前传进来的是executeOnExecutor(sDefaultExecutor, params),原来是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<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); } } }
原来sDefaultExecutor就是一个SerialExecutor线程池。而mTasks其实是一个线程任务队列。
ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
当没有正在活动的AsyncTask任务,就会调用scheduleNext()这个方法。
那我们再看看这个方法是怎样的:
protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } }
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
这里又出现一个线程池THREAD_POOL_EXECUTOR,原来真正地执行任务的是THREAD_POOL_EXECUTOR线程池,而SerialExecutor这个线程是用于任务的队列。
好了,我们先来总结一部分先,AsyncTask的排队执行过程。首先系统会将传进来的参数params封装到mWorker这个线程中,接着mWorker这个参数会传进FutureTask对象中去。因为FuntureTask相当于是一个线程,第一个线程池SerialExecutor就会把这个mFuture这个线程插进任务队列,如果当前没有执行的AsyncTask,就会调用scheduleNext(),就是THREAD_POOL_EXECUTOR这个真正执行任务的。而从SerialExecutor的execute()方法可以看出,AsyncTask任务执行完成之后,会继续执行scheduleNext(),所以这可以看出AsyncTask默认情况下是串行的。
来到这里的话,基本就分析完毕了,但是好像漏了之前postResult(result)这个方法。从名字上可以看出,这个方法应该就是将结果返回到主线程中,那我们来验证一下。
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
在这里我们看到了熟悉的Message,本能反应的,应该会想到应该有一个handler。
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; } } }
没错,就是通过发送MESSAGE_POST_RESULT这个消息通知InternalHandler,再调用finish()方法。
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
而InternalHandler是在主线程中创建的,所以可以访问UI控件。这也就是要求我们的AsyncTask的类必须要在主线程中创建。
至此,AsyncTask的源码和工作流程就分析完毕了。这里再补充两点:
- Android 3.0以前,是并发的
- Android 3.0以后,默认情况下是串行的,相当于是单线程执行。如果想要在3.0及以上并发,就可以采用AsyncTask的executeOnExecutor()方法
- AsyncTask工作原理解析
- Android源码解析AsyncTask的工作原理
- Android 源码解析AsyncTask的工作原理
- 从AsyncTask的源码解析AsyncTask工作原理
- 源码解析Android中AsyncTask的工作原理
- android多线程-AsyncTask之工作原理深入解析(上)
- android多线程-AsyncTask之工作原理深入解析(下)
- Android AsyncTask 源码详细解析,掌握工作原理和细节
- 源码解析Android中AsyncTask的工作原理
- 源码解析Android中AsyncTask的工作原理
- android多线程-AsyncTask之工作原理深入解析(上)
- android多线程-AsyncTask之工作原理深入解析(下)
- AsyncTask工作原理
- AsyncTask工作原理
- AsyncTask的工作原理
- AsyncTask工作原理分析
- Android AsyncTask工作原理
- AsyncTask工作原理
- 希尔排序(比较难)
- 【京东校招笔试】采购单
- SQLAlchemy_定义(一对一/一对多/多对多)关系
- python安装教程及环境配置
- 【51单片机学习过程记录】4矩阵键盘
- AsyncTask工作原理解析
- 整理常用的十个git命令
- 82. Remove Duplicates from Sorted List II
- 链表的一些简单操作
- QT的信号与槽机制介绍
- [总结贴]虚拟机安装MAC OS X 10.10
- MySQL不支持FULL JOIN, INTERSECT和MINUS(except)的替代方法
- 专题总结:数据结构总结【转】
- aaaaaaaaa