时间:2021-05-21
Android AsyncTask实现机制
示例代码:
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } 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; }execute先调用onPreExecute()(可见,onPreExecute是自动调用的)然后调用exec.execute(mFuture)
public interface Executor { void execute(Runnable command); }这是一个接口,具体实现在
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); } } }从上面可知,AsyncTask执行过程如下:先执行onPreExecute,然后交给SerialExecutor执行。在SerialExecutor中,先把Runnable添加到mTasks中。
如果没有Runnable正在执行,那么就调用SerialExecutor的scheduleNext。同时当一个Runnable执行完以后,继续执行下一个任务
AsyncTask中有两个线程池,THREAD_POOL_EXECUTOR和SERIAL_EXECUTOR,以及一个Handler–InternalHandler
/** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); /** * An {@link Executor} that executes tasks one at a time in serial * order. This serialization is global to a particular process. */ public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static InternalHandler sHandler;SERIAL_EXECUTOR用于任务的排列,THREAD_POOL_EXECUTOR真正执行线程,InternalHandler用于线程切换
先看构造函数
看到了熟悉的doInBackground了吧,然后调用postResult
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }主线程中创建InternalHandler并发送MESSAGE_POST_RESULT消息,然后调用finish函数
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; } } } private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }finish中调用onPostExecute。
AsyncTask工作流程:new MyThread().execute(1);
先构造函数,然后execute
构造函数只是准备了mWorker和mFuture这两个变量
execute中调用onPreExecute,然后exec.execute(mFuture),其中响应了call函数,call中调用doInBackground,然后将结果传给Handler然后finish掉,finish函数调用onPostExecute
你可能会奇怪,为什么没有onProgressUpdate,有注解可以解释
/** * Runs on the UI thread after {@link #publishProgress} is invoked. * The specified values are the values passed to {@link #publishProgress}. * * @param values The values indicating progress. * * @see #publishProgress * @see #doInBackground */ @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) { }也就是说必须调用publishProgress才会自动调用onProgressUpdate。
那如何调用publishProgress呢?
doInBackground说的很明确,在doInBackground函数里面显示调用publishProgress即可。
publishProgress源码:
protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } 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; } } }感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
AsyncTask的介绍及基本使用方法关于AsyncTask的介绍和基本使用方法可以参考官方文档和《Android开发笔记之:深入理解多线程AsyncTask》
在Android当中,提供了两种方式来解决线程直接的通信问题,一种是通过Handler的机制,还有一种就是今天要详细讲解的AsyncTask机制。AsyncTa
本文实例为大家分享了AsyncTask异步类实现网页内容放大缩小的详细代码,供大家参考,具体内容如下WebActivity.java:packagecom.su
本文实例讲述了Android基于广播事件机制实现简单定时提醒功能代码。分享给大家供大家参考,具体如下:1.Android广播事件机制Android的广播事件处理
Android中Handler与Message的简单实例前言:虽然笔者已经学习了Android的AsyncTask来实现一部消息的处理。但是在android的学