程序员人生 网站导航

Android:AsyncTask

栏目:综合技术时间:2016-05-09 11:27:35

AsyncTask是异步任务,在不阻塞UI线程的情况下,在后台处理复杂逻辑,并将结果返回到UI线程,现在来分析1下AsyncTask的实现。

先来看看我们常见的使用方法。

先声明1个类,继承自AsyncTask

class MyTask extends AsyncTask{ @Override protected Integer doInBackground(Void... params) { // TODO Auto-generated method stub return null; } }
然后使用它


MyTask task; task = new MyTask(); task.execute();
具体AsyncTask都做了甚么,1步步看。在AsyncTask内部有两个很重要的对象



private final WorkerRunnable mWorker; private final FutureTaskmFuture;
先看看WorkerRunnable



private static abstract class WorkerRunnable implements Callable{ Params[] mParams; }
WorkerRunnable继承自Callable,Callable的官方说明是:Callable和Runnable类似,都是可以在另外一个线程中履行的,但是2者还是有区分的。


1、Callable的接口方法是call,Runnable是run

2、Callable可以带返回值,Runnable不行

3、Callable可以捕获异常,Runnable不行


public interface Callable{ /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
再看看FutureTask,FutureTask是异步计算的结果,继承关系是 FutureTask -> RunnableFuture->Runnable, Future,FutureTask内部可以判断任务的履行状态,并切可以取消任务。


FutureTask的构造函数接收1个Callable类型参数,赋值给callable对象

public FutureTask(Callablecallable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }


上面的WorkerRunnable被传入,在FutureTask的run方法中,调用WorkerRunnable的call方法履行,并返回结果。

public void run() { ...... try { Callablec = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { ...... } if (ran) set(result); } } finally { ...... } }

下面就来看看AsyncTask的初始化


public AsyncTask() { mWorker = new WorkerRunnable() { public Result call() throws Exception { ...... } }; mFuture = new FutureTask(mWorker) { @Override protected void done() { ...... } }; }
我们看到,之条件到过的两个对象,在这里被创建,mFuture实现了done的重载,就是任务完成后,履行此处代码。当我们履行execute方法是,调用的是下面代码


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; }
通过 exec.execute(mFuture); 开始履行任务,execute需要Runnable类型对象,mFuture就是FutureTask类型对象,继承自Runnable。


再看看结果取得后,返回的动作。

FutureTask中的run方法中通过 callable 开始履行任务,任务结束后,会履行set方法

public void run() { ...... try { Callablec = callable; if (c != null && state == NEW) { ...... if (ran) set(result); } } finally { ...... } }
set方法中履行结束任务的方法 finishCompletion,这里就会调用 done 接口,就通知到了AsyncTask的mFuture的done回调


protected void set(V v) { if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { outcome = v; UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state finishCompletion(); } }
private void finishCompletion() { // assert state > COMPLETING; ...... done(); callable = null; // to reduce footprint }
mFuture的done回调中会通过postResultIfNotInvoked调用postResult直接提交结果,那末对另外一个对象mWorker来讲,在call回调中,通过postResult(doInBackground(mParams));去提交结果,所以 doInBackground 是我们必须实现的1个接口函数。


postResult中通过内部的1个handler,去通知UI进程,并处理 onPostExecute 及 onProgressUpdate 接口的实现。这样就完成了任务的全部传递。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐