Android:AsyncTask

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

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

先声明一个类,继承自AsyncTask

    class MyTask extends AsyncTask<Void,Integer,Integer>{

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

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

    private final WorkerRunnable<Params, Result> mWorker;
    private final FutureTask<Result> mFuture;
先看看WorkerRunnable

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

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

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

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

public interface Callable<V> {
    /**
     * 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的构造函数接收一个Callable类型参数,赋值给callable对象

    public FutureTask(Callable<V> callable) {
        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 {
            Callable<V> c = 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<Params, Result>() {
            public Result call() throws Exception {
                ......
            }
        };

        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                ......
            }
        };
    }
我们 看到,之前提到过的两个对象,在这里被创建,mFuture实现了done的重载,就是任务完成后,执行此处代码。当我们执行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) {
        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 {
            Callable<V> c = 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 是我们必须实现的一个接口函数。

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






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bdmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值