Android AsyncTask实现机制详细介绍及实例代码
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用于线程切换
先看构造函数
public asynctask() { mworker = new workerrunnable<params, result>() { public result call() throws exception { mtaskinvoked.set(true); process.setthreadpriority(process.thread_priority_background); //noinspection unchecked return postresult(doinbackground(mparams)); } }; 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 occured while executing doinbackground()", e.getcause()); } catch (cancellationexception e) { postresultifnotinvoked(null); } } }; }
看到了熟悉的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呢?
/** * override this method to perform a computation on a background thread. the * specified parameters are the parameters passed to {@link #execute} * by the caller of this task. * * this method can call {@link #publishprogress} to publish updates * on the ui thread. * * @param params the parameters of the task. * * @return a result, defined by the subclass of this task. * * @see #onpreexecute() * @see #onpostexecute * @see #publishprogress */ protected abstract result doinbackground(params... params);
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; } } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
上一篇: day11-java内存区域